#define ALONE_UTI_TWN

#include "Uti_Tianwan.h"

int		vtwSleep;

BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module
					DWORD fdwReason,     // reason for calling function
					LPVOID lpReserved )  // reserved
					{
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
    DWORD	dwBufLen;
	DWORD	active;
    
	size = 0;
	data = 0;
	type = 0;
	
	switch(fdwReason){ 
		case DLL_PROCESS_ATTACH:
			res = RegOpenKeyEx(	HKEY_LOCAL_MACHINE, 
							TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Uti_Tianwan"),
							0,
							KEY_QUERY_VALUE,
							&hKey);
			if(res != ERROR_SUCCESS)
				return(FALSE);	
			
			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("VTWSleep"),
									NULL,
									NULL,
									(LPBYTE)active,
									&dwBufLen);
			if(res == ERROR_SUCCESS)
				vtwSleep = active;
			else
				vtwSleep = SLEEP_BETWEEN_WRITE;
			
			RegCloseKey(hKey);
			break;
		default:
			break;
	}
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

/*------------------------------------------------------------------------------
** Function:		GetZoneName
**
** Description:		Get Zone Name using Zone Idx
**
** Input:			ZoneIdx	- Zone Idx
** Output:			ZoneName	- Zone Name
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneName		( GENIDX ZoneIdx, ZONENAME ZoneName )
{
  RETCOND	stat;
  t_zone	zone;
  FILEIDX   file;

  ZoneName[0] = '\0';
  file.num = F_ZONE;
  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone));
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  _tcsncpy_s(ZoneName,sizeof(ZoneName), zone.name, L_ZONE_NAM );
  ZoneName[L_ZONE_NAM] = '\0';

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneIdx
**
** Description:		Get Zone Idx using Zone Name 
**
** Input:			ZoneName	- Zone Name
** Output:			ZoneIdx		- Zone Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Name
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneIdx		( ZONENAME ZoneName, GENIDX *ZoneIdx )
{
  RETCOND	stat;
  t_zone	zone;
  FILEIDX   file;
  int		i;

  *ZoneIdx = (GENIDX)0;
  file.num = F_ZONE;
  if ( !_tcscmp( ZoneName, _T("") ) )
    return (RT_INVZONE);

  for ( i = 0; i < N_MAX_ZONE; i++ )
   {
    stat = FileRead(&file, (i+1), 1, &zone, sizeof(t_zone) );

    if ( !_tcsncmp ( ZoneName, zone.name, L_ZONE_NAM ) )
     {
      *ZoneIdx = (GENIDX)(i+1);
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneIdxVirtCoo
**
** Description:		Get Zone Idx using Virtual Coordinate X & Y
**
** Input:			Coo_X		- Virtual Coordinate X
**					Coo_Y		- Virtual Coordinate Y
** Output:			ZoneIdx		- Zone Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/
RETSTAT GetZoneIdxVirtCoo(int Coo_X, int Coo_Y, GENIDX *ZoneIdx){
	RETSTAT		retSt;
	int			i;
	int			minVx;
	int			maxVx;
	int			minVy;
	int			maxVy;
	int			virtFlag;

	*ZoneIdx = (GENIDX)(0);

	for(i = 1; i <= N_MAX_ZONE; i++){
		retSt = GetZoneVirtLimits(i, &minVx, &maxVx, &minVy, &maxVy);
		if(retSt != RT_NORMAL)
			return(retSt);

		retSt = IsVirtualZoneIdx((GENIDX)(i), &virtFlag);
		if((retSt != RT_NORMAL) || (virtFlag != 0))
			continue;

		if((Coo_X >= minVx) && (Coo_X <= maxVx) && (Coo_Y >= minVy) && (Coo_Y <= maxVy)){
			*ZoneIdx = (GENIDX)(i);
			return(RT_NORMAL);
		}
	}

	return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneVirtLimits
**
** Description:		Get Zone virtual coordinates limits
**
** Input:			zoneIdx		- Zone Idx
**					
** Output:			minVx		- Min virtual X coordinate
**					maxVx		- Max virtual X coordinate
**					minVy		- Min virtual Y coordinate
**					maxVy		- Max virtual Y coordinate
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_FAILED	If Zone not exist
*/
RETSTAT GetZoneVirtLimits(GENIDX zoneIdx, int *minVx, int *maxVx, int *minVy, int *maxVy){
	RETCOND		stat;
	t_zone		zone;
	FILEIDX		file;

	*minVx = 0;
	*maxVx = 0;
	*minVy = 0;
	*maxVy = 0;

	file.num = F_ZONE;
	
	stat = FileRead(&file , zoneIdx, 1, &zone, sizeof(t_zone) );
	if(stat != R_NORMAL)
		return(RT_FAILED);

	*minVx = zone.minVirtX;
	*maxVx = zone.maxVirtX;
	*minVy = zone.minVirtY;
	*maxVy = zone.maxVirtY;
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		IsCorrPosition
**
** Description:		Check if a physicsl point is in corridor
**
** Input:			px			- Point x coordinate
**					py			- Point y coordinate
**					
** Return:			RETSTAT		- RT_NORMAL	If px,py is in corridor
**								- RT_FAILED	If otherwise
*/
RETSTAT IsCorrPosition(float px, float py){
	RETSTAT			retSt;

	float			leftX;
	float			rightX;
	float			lowY;
	float			highY;
	
	//Check C23//
	retSt = GetInfiBlockValEx(8326, 0, TUNE_FROM_DAFS, &leftX);
	retSt = GetInfiBlockValEx(8327, 0, TUNE_FROM_DAFS, &rightX);
	retSt = GetInfiBlockValEx(8333, 0, TUNE_FROM_DAFS, &lowY);
	retSt = GetInfiBlockValEx(8332, 0, TUNE_FROM_DAFS, &highY);

	if((px >= (float)(leftX - TOLL_MM))			&& 
	   (px <= (float)(rightX + TOLL_MM))		&&
	   (py >= (float)(lowY - TOLL_MM))			&&
	   (py <= (float)(highY + TOLL_MM)))
		return(RT_NORMAL);

	//Check C21//
	retSt = GetInfiBlockValEx(8324, 0, TUNE_FROM_DAFS, &leftX);
	retSt = GetInfiBlockValEx(8325, 0, TUNE_FROM_DAFS, &rightX);
	retSt = GetInfiBlockValEx(8337, 0, TUNE_FROM_DAFS, &lowY);
	retSt = GetInfiBlockValEx(8330, 0, TUNE_FROM_DAFS, &highY);

	if((px >= (float)(leftX - TOLL_MM))			&& 
	   (px <= (float)(rightX + TOLL_MM))		&&
	   (py >= (float)(lowY - TOLL_MM))			&&
	   (py <= (float)(highY + TOLL_MM)))
		return(RT_NORMAL);

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneIdxPhisCoo
**
** Description:		Get Zone Idx using Phisical Coordinate X & Y
**
** Input:			Coo_X		- Phisical Coordinate X
**					Coo_Y		- Phisical Coordinate Y
** Output:			ZoneIdx		- Zone Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/
RETSTAT GetZoneIdxPhisCoo(float Coo_X, float Coo_Y, GENIDX *ZoneIdx){
	RETCOND		stat;
	RETSTAT		retSt;
	t_zone		zone;
	int			i;
	FILEIDX		file;
	float		diff;
	float		temp;
	GENIDX		mainPoolIdx;

	*ZoneIdx = (GENIDX)0;

	file.num = F_ZONE;

	retSt = GetZoneIdx(ZONE_MAIN, &mainPoolIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	for(i = 0; i < N_MAX_ZONE; i++){
	  
		if(i == mainPoolIdx - 1)
			continue;

		stat = FileRead(&file , (i+1), 1, &zone, sizeof(t_zone) );
		if((zone.zone_coord.L_H_CooX == 0) &&
		   (zone.zone_coord.L_H_CooY == 0) &&
           (zone.zone_coord.R_L_CooX == 0) &&
           (zone.zone_coord.R_L_CooY == 0))
			break;
		
		if((Coo_X >= zone.zone_coord.L_H_CooX - (float)(TOLL_MM)) &&
		   (Coo_Y <= zone.zone_coord.L_H_CooY + (float)(TOLL_MM)) &&
           (Coo_X <= zone.zone_coord.R_L_CooX + (float)(TOLL_MM)) &&
           (Coo_Y >= zone.zone_coord.R_L_CooY - (float)(TOLL_MM))){
			*ZoneIdx = (GENIDX)(i+1);
			return (RT_NORMAL);
		}
	}
	
	diff = (float)(999999.9);
	for(i = 0; i < N_MAX_ZONE; i++){

		if(i == mainPoolIdx - 1)
			continue;

		stat = FileRead(&file , (i+1), 1, &zone, sizeof(t_zone));
		
		temp = ((Coo_X - zone.zone_coord.L_H_CooX) * (Coo_X - zone.zone_coord.L_H_CooX)) + ((Coo_Y - zone.zone_coord.L_H_CooY) * (Coo_Y - zone.zone_coord.L_H_CooY));
		if(temp < diff){
			diff = temp;
			*ZoneIdx = (GENIDX)(i+1);
		}
		
		temp = (((Coo_X - zone.zone_coord.R_L_CooX) * (Coo_X - zone.zone_coord.R_L_CooX)) + ((Coo_Y - zone.zone_coord.R_L_CooY) * (Coo_Y - zone.zone_coord.R_L_CooY)));
		if(temp < diff){
			diff = temp;
			*ZoneIdx = (GENIDX)(i+1);
		}

		temp = (((Coo_X - zone.zone_coord.L_H_CooX) * (Coo_X - zone.zone_coord.L_H_CooX)) + ((Coo_Y - zone.zone_coord.R_L_CooY) * (Coo_Y - zone.zone_coord.R_L_CooY)));
		if(temp < diff){
			diff = temp;
			*ZoneIdx = (GENIDX)(i+1);
		}

		temp = (((Coo_X - zone.zone_coord.R_L_CooX) * (Coo_X - zone.zone_coord.R_L_CooX)) + ((Coo_Y - zone.zone_coord.L_H_CooY) * (Coo_Y - zone.zone_coord.L_H_CooY)));
		if(temp < diff){
			diff = temp;
			*ZoneIdx = (GENIDX)(i+1);
		}
	}
	
	if(diff != 999999.9)
		return (RT_NORMAL);
	else
		return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneCoord
**
** Description:		Get Zone Coordinate using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
** Output:			L_H_CooX	- Zone X left high Coord
**					L_H_CooY	- Zone Y left high Coord
**					R_L_CooX	- Zone X right low Coord
**					R_L_CooY	- Zone Y right low Coord
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneCoord		( GENIDX ZoneIdx, float *L_H_CooX, float *L_H_CooY,
					float *R_L_CooX, float *R_L_CooY )
{
  RETCOND	stat;
  t_zone	zone;
  FILEIDX   file;
  
  file.num = F_ZONE;
  *L_H_CooX = 0.0;
  *L_H_CooY = 0.0;
  *R_L_CooX = 0.0;
  *R_L_CooY = 0.0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *L_H_CooX = zone.zone_coord.L_H_CooX;
  *L_H_CooY = zone.zone_coord.L_H_CooY;
  *R_L_CooX = zone.zone_coord.R_L_CooX;
  *R_L_CooY = zone.zone_coord.R_L_CooY;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNumForbArea
**
** Description:		Get Number of Forbidden Areas using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
** Output:			NumForbArea	- Zone Number of Forbidden Areas
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneNumForbArea	( GENIDX ZoneIdx, int *NumForbArea )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;

  file.num = F_ZONE;
  *NumForbArea = 0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead(&file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *NumForbArea = zone.n_forb_area;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneForbAreaCoord
**
** Description:		Get Coord. of Forb. Area using Zone Idx & Forb Area index
**
** Input:			ZoneIdx		- Zone Idx
**					NumForbArea	- Forbidden Area Index
** Output:			L_H_CooX	- Forbidden Area X left high Coord
**					L_H_CooY	- Forbidden Area Y left high Coord
**					R_L_CooX	- Forbidden Area X right low Coord
**					R_L_CooY	- Forbidden Area Y right low Coord
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_INVFORB	If invalid Forb. area Index
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneForbAreaCoord 	( GENIDX ZoneIdx, int NumForbArea,
					float *L_H_CooX, float *L_H_CooY,
					float *R_L_CooX, float *R_L_CooY )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;
  
  file.num = F_ZONE;
  *L_H_CooX = 0.0;
  *L_H_CooY = 0.0;
  *R_L_CooX = 0.0;
  *R_L_CooY = 0.0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( NumForbArea <= 0 ) || ( NumForbArea > N_MAX_FORB ) )
    return (RT_INVFORB);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *L_H_CooX = zone.forb_area[NumForbArea-1].L_H_CooX;
  *L_H_CooY = zone.forb_area[NumForbArea-1].L_H_CooY;
  *R_L_CooX = zone.forb_area[NumForbArea-1].R_L_CooX;
  *R_L_CooY = zone.forb_area[NumForbArea-1].R_L_CooY;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNumLegalPath
**
** Description:		Get Number of Legal Path using Zone Idx
**
** Input:			ZoneIdx			- Zone Idx
** Output:			NumLegalPath	- Number of Legal Path
**
** Return:			RETSTAT			- RT_NORMAL	If Zone exist
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
** Da modificare dopo aver scelto la struttura dei nuovi legal path.
*/

RETSTAT GetZoneNumLegalPath	( GENIDX ZoneIdx, int *NumLegalPath )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX file;

  file.num = F_ZONE;
  *NumLegalPath = 0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *NumLegalPath = zone.n_legal_path;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneLegalPath
**
** Description:		Get Legal Path using Zone Idx
**
** Input:			ZoneIdx			- Zone Idx
**					NumLegalPath	- Legal Path index
** Output:			Legal_Path		- Legal Path
**
** Return:			RETSTAT			- RT_NORMAL	If Zone exist
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_INVPATH	If invalid Path Index
**									- RT_FAILED	If Zone not exist
** Da modificare dopo aver scelto la struttura dei nuovi legal path.
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneLegalPath	( GENIDX ZoneIdx, int NumLegalPath,
					LEGALPATH *Legal_Path )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;

  file.num = F_ZONE;

  memset ( Legal_Path, 0, sizeof ( LEGALPATH ) );

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( NumLegalPath <= 0 ) || ( NumLegalPath > N_MAX_PATH ) )
    return (RT_INVPATH);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  if ( NumLegalPath <= zone.n_legal_path )
   {
    memcpy ( Legal_Path, &zone.legal_path[NumLegalPath-1], sizeof (LEGALPATH) );
    return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneFinalLegalPath
**
** Description:		Get Legal Path using Zone Idx and Final Zone Idx
**
** Input:			ZoneIdx			- Zone Idx
**					FinalZoneIdx	- Final Zone Idx
** Output:			Legal_Path		- Legal Path
**
** Return:			RETSTAT			- RT_NORMAL	If Zone exist
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
** Da modificare dopo aver scelto la struttura dei nuovi legal path.
*/

RETSTAT GetZoneFinalLegalPath	( GENIDX ZoneIdx, GENIDX FinalZoneIdx,
					LEGALPATH *Legal_Path )
{
  RETCOND	stat;
  t_zone	zone;
  int		i;
  int		ind;
  FILEIDX   file;

  file.num = F_ZONE;
  
  memset ( Legal_Path, 0, sizeof ( LEGALPATH ) );

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( FinalZoneIdx <= 0 ) || ( FinalZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  for ( i = 0; i < zone.n_legal_path; i++ )
   {
    if ( i >= N_MAX_PATH )
      break;
    ind = (zone.legal_path[i].n_zone - 1);
    if ( zone.legal_path[i].zone[ind] == FinalZoneIdx )
     {
      memcpy ( Legal_Path, &zone.legal_path[i], sizeof (LEGALPATH) );
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNumConfZone
**
** Description:		Get Number of Confinant Zones using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
** Output:			NumConfZone	- Number of Confinant Zones
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneNumConfZone	( GENIDX ZoneIdx, int *NumConfZone )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;
  *NumConfZone = 0;

  file.num = F_ZONE;
  
  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *NumConfZone = zone.n_conf_zone;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneConfZoneIdx
**
** Description:		Get Idx of Confinant Zone using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
**					NumConfZone	- Confinant Zone Index
** Output:			ConfZoneIdx	- Zone Idx of confinant Zone
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_INVCONF	If invalid Conf. zone Index
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneConfZoneIdx	( GENIDX ZoneIdx, int NumConfZone,
					GENIDX *ConfZoneIdx )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;

  file.num = F_ZONE;

  *ConfZoneIdx = (GENIDX)0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( NumConfZone <= 0 ) || ( NumConfZone > N_MAX_CONF ) )
    return (RT_INVCONF);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *ConfZoneIdx = (GENIDX)zone.conf_zone[NumConfZone-1].zone;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneCoordCorr
**
** Description:		Get Coordinate of Corrid. Confinant Zone using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
**					NumConfZone	- Confinant Zone Index
** Output:			Corr_X		- [X] array of corridor n. points
					Corr_Y		- [Y] array of corridor n. points
**					n_points	- number of corridor points.
**
** Return:			RETSTAT		- RT_NORMAL	If Zone exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_INVCONF	If invalid Conf. zone Index
**								- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

/*
RETSTAT GetZoneCoordCorr	( GENIDX ZoneIdx, int NumConfZone,
					float *Corr_X, float *Corr_Y )
*/
 RETSTAT GetZoneCoordCorr	( GENIDX ZoneIdx, int NumConfZone,
					float *Corr_X, float *Corr_Y, int *n_points)
{
  RETCOND	stat;
  t_zone	zone;
  int		i,j;
  FILEIDX   file;

  file.num = F_ZONE;

  *n_points = 0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( NumConfZone <= 0 ) || ( NumConfZone > N_MAX_CONF ) )
    return (RT_INVCONF);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);
//Modifica qui per variazione struttura corridoi
 /*
  *Corr_X = zone.conf_zone[NumConfZone-1].Corr_X;
  *Corr_Y = zone.conf_zone[NumConfZone-1].Corr_Y;
*/
 i = zone.conf_zone[NumConfZone -1].n_point;
 *n_points = i;
 if (i != 0){
	 Corr_X = new float[i];
	 Corr_Y = new float[i];
	 for(j = 0; j< i; j++){
		 Corr_X[j] = zone.conf_zone[NumConfZone -1].corr_point[j][0];
		 Corr_Y[j] = zone.conf_zone[NumConfZone -1].corr_point[j][1];
	 }
	  return (RT_NORMAL);
 }
 else
	 return (RT_INVCORR);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneConfCoordCorr
**
** Description:		Get Coord. of Corrid. Conf. Zone using Zone & ConfZone Idx
**
** Input:			ZoneIdx		- Zone Idx
**					ConfZoneIdx	- Confinant Zone Idx
** Output:			Corr_X		- [X] Array Coord. of Zone confinant Zone (n_points element).
**					Corr_Y		- [Y] Array Coord. of Zone confinant Zone (n_points element).
**					n_points	- Number of corridor points
**
** Return:			RETSTAT		- RT_NORMAL	If Zone and Conf. Zone exist
**								- RT_INVZONE	If invalid Zone or Conf. Idx
**								- RT_FAILED	If Zone or Conf. Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneConfCoordCorr	( GENIDX ZoneIdx, GENIDX ConfZoneIdx,
									float *Corr_X, float *Corr_Y, int *n_points )
{
  RETCOND	stat;
  t_zone	zone;
  int		i,j;
  FILEIDX	file;

  file.num = F_ZONE;

  *n_points = 0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( ConfZoneIdx <= 0 ) || ( ConfZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  for ( i = 0; i < zone.n_conf_zone; i++ )
   {
    if ( i >= N_MAX_CONF )
      break;
    if ( zone.conf_zone[i].zone == ConfZoneIdx )
     {
//Modifica qui per variazione struttura corridoi
		/*
	  *Corr_X = zone.conf_zone[i].Corr_X;
      *Corr_Y = zone.conf_zone[i].Corr_Y;
		*/
	  *n_points = zone.conf_zone[i].n_point;
	  if(*n_points == 0){
		  return (RT_INVCORR);
	  }
	  Corr_X = new float[*n_points];
	  Corr_Y = new float[*n_points];
	  for(j = 0; j< *n_points; j++){
		 Corr_X[j] = zone.conf_zone[i].corr_point[j][0];
		 Corr_Y[j] = zone.conf_zone[i].corr_point[j][1];
		}

      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNumAllowedObj
**
** Description:		Get Number of Allowed Object using Zone Idx
**
** Input:			ZoneIdx			- Zone Idx
** Output:			NumAllowedObj	- Number of Allowed Object
**
** Return:			RETSTAT			- RT_NORMAL	If Zone exist
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.				
*/

RETSTAT GetZoneNumAllowedObj	( GENIDX ZoneIdx, int *NumAllowedObj )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;

  file.num = F_ZONE;

  *NumAllowedObj = 0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *NumAllowedObj = zone.n_all_obj;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneAllowedObjIdx
**
** Description:		Get Idx of Allowed Object using Zone Idx
**
** Input:			ZoneIdx			- Zone Idx
**					NumAllowedObj	- Allowed Object Index
** Output:			AllowedObjIdx	- Idx of Allowed Object
**
** Return:			RETSTAT			- RT_NORMAL	If Zone exist
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_INVOBJT	If invalid Allowed Object Index
**									- RT_FAILED	If Zone not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneAllowedObjIdx	( GENIDX ZoneIdx, int NumAllowedObj,
					GENIDX *AllowedObjIdx )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  FILEIDX   file;

  file.num = F_ZONE;

  *AllowedObjIdx = (GENIDX)0;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( NumAllowedObj <= 0 ) || ( NumAllowedObj > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  *AllowedObjIdx = (GENIDX)zone.all_obj[NumAllowedObj-1].obj_t;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneVirtPar
**
** Description:		Get Zone Idx & Virtual Parameters using Virtual Coord. X & Y
**
** Input:			VCoo_X		- Virtual Coordinate X
**					VCoo_Y		- Virtual Coordinate Y
** Output:			ZoneIdx		- Zone Idx
**					Cell		- Cell Virtual Parameters
**
** Return:			RETSTAT		- RT_NORMAL	If Cell Virtual Param exist
**								- RT_FAILED	If Cell Virtual Param not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneVirtPar		( int VCoo_X, int VCoo_Y,
					GENIDX *ZoneIdx, t_cell *Cell )
{
  RETCOND	stat;
  t_cell	cell;
  int		i, j;
  FILEIDX	file;

  *ZoneIdx = (GENIDX)0;
  memset ( Cell, 0, sizeof ( t_cell ) );

  for ( i = 0; i < N_MAX_ZONE; i++ )
   {
    file.num = F_CE01 + i;

    for ( j = 0; j < N_MAX_CELL; j++ )
     {
      stat = FileRead( &file, (j+1), 1, &cell, sizeof(t_cell) );
      if ( stat != RT_NORMAL )
        return (RT_FAILED);
        

      if ( ( cell.Virt_X == 0 ) &&
	   ( cell.Virt_Y == 0 ) )
	break;

      if ( ( cell.Virt_X == VCoo_X ) &&
	   ( cell.Virt_Y == VCoo_Y ) )
       {
	*ZoneIdx = (GENIDX)(i+1);
	memcpy ( Cell, &cell, sizeof ( t_cell ) );
        return (RT_NORMAL);
       }
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneFirstVirtPar
**
** Description:		Get First Virtual Parameters using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
**
** Output:			Cell		- Cell Virtual Parameters
**
** Return:			RETSTAT		- RT_NORMAL	If Cell Virtual Param exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_FAILED	If Cell Virtual Param not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZoneFirstVirtPar	( GENIDX ZoneIdx, t_cell *Cell )
{
  RETCOND	stat;
  t_cell	cell;
//  int		i, j;
  FILEIDX	file;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  memset ( Cell, 0, sizeof ( t_cell ) );

  file.num = F_CE01 + ((int)ZoneIdx - 1);

  stat = FileRead( &file, 1, 1, &cell, sizeof(t_cell) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( ( cell.Virt_X == 0 ) &&
       ( cell.Virt_Y == 0 ) )
    return (RT_FAILED);

  memcpy ( Cell, &cell, sizeof ( t_cell ) );

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZonePhisVirtCoord
**
** Description:		Get Virtual Coordinate X & Y using Phisical Coordinate X & Y
**
** Input:			Coo_X		- Phisical Coordinate X
**					Coo_Y		- Phisical Coordinate Y
** Output:			VCoo_X		- Virtual Coordinate X
**					VCoo_Y		- Virtual Coordinate Y
**
** Return:			RETSTAT		- RT_NORMAL	If Virtual Coord exist
**								- RT_FAILED	If Virtual Coord not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZonePhisVirtCoord(float Coo_X, float Coo_Y, int *VCoo_X, int *VCoo_Y){
	RETCOND			stat;
	RETSTAT			retSt;
	FILEIDX			file;
	GENIDX			zoneIdx;
	GENIDX			zoneIOIdx;
	t_cell			cell;
	int				j;
	int				contIdx;
	int				cellContIdx;
	int				startRec;
	int				stopRec;
	float			AppX;
	float			AppY;
	float			toll;

	*VCoo_X = 0;
	*VCoo_Y = 0;

	retSt = GetZoneIdx(ZONE_IO, &zoneIOIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdxPhisCoo(Coo_X, Coo_Y, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	file.num = F_CE01 + zoneIdx - 1;
	
	retSt = GetPositToll(&toll);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(zoneIdx == zoneIOIdx){
		GetDynCurrentCont(&contIdx);
		if(contIdx == Z1_NO_CONT)
			return(RT_FAILED);
		else if(contIdx == Z1_CONT_TK13){
			startRec = 1;
			stopRec = CONT_TK13_CELLS;
		}
		else if(contIdx == Z1_CONT_LOAD){
			startRec = CONT_TK13_CELLS + 1;
			stopRec = startRec + CONT_LOAD_CELLS;
		}
		else if(contIdx == Z1_CONT_HECA){
			startRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + 1;
			stopRec = N_MAX_CELL;
		}
	}
	else{
		startRec = 1;
		stopRec = N_MAX_CELL;
	}

	for(j = startRec; j <= stopRec; j++){
		stat = FileRead(&file, j, 1, &cell, sizeof(t_cell));
		if(stat != RT_NORMAL)
			return(RT_FAILED);
        
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			break;

		AppX = (cell.Phys_X - Coo_X);
		if(AppX < 0.0)
			AppX =(float)(AppX * (-1.0));
		AppY = (cell.Phys_Y - Coo_Y);
		if(AppY < 0.0)
			AppY = (float)(AppY * (-1.0));

		if((AppX <= toll) && (AppY <= toll)){
			*VCoo_X = (int)cell.Virt_X;
			*VCoo_Y = (int)cell.Virt_Y;

			if(zoneIdx == zoneIOIdx){
				retSt = GetCotainIdxFromCell(cell.Virt_X, cell.Virt_Y, &cellContIdx);
				if(retSt != RT_NORMAL)
					return(RT_FAILED);
				
				if(contIdx != cellContIdx)
					return(RT_FAILED);
			}

			return (RT_NORMAL);
		}
	}

	return (RT_FAILED);
/*
	OLD  15/1/2003
  for ( i = 0; i < N_MAX_ZONE; i++ )
   {
    file.num = F_CE01 + i;
    for ( j = 0; j < N_MAX_CELL; j++ )
     {
      stat = FileRead( &file, (j+1), 1, &cell, sizeof(t_cell) );
      if ( stat != RT_NORMAL )
        return (RT_FAILED);
        
      if ( ( cell.Virt_X == 0 ) &&
	   ( cell.Virt_Y == 0 ) )
	break;

      AppX = (cell.Phys_X - Coo_X);
      if ( AppX < 0.0 )
        AppX =(float)( AppX * (-1.0));
      AppY = (cell.Phys_Y - Coo_Y);
      if ( AppY < 0.0 )
        AppY = (float)(AppY * (-1.0));

      if ( ( AppX <= TOLL_MM ) &&
	   ( AppY <= TOLL_MM ) )
       {
	*VCoo_X = (int)cell.Virt_X;
	*VCoo_Y = (int)cell.Virt_Y;
        return (RT_NORMAL);
       }
     }
   }

  return (RT_FAILED);
*/
}

/*------------------------------------------------------------------------------
** Function:		GetZonePhisVirtCoordEx
**
** Description:		Get Virtual Coordinate X & Y using Phisical Coordinate X & Y
**
** Input:			Coo_X		- Phisical Coordinate X
**					Coo_Y		- Phisical Coordinate Y
**					Virt		- Look for virtual cell only
** Output:			VCoo_X		- Virtual Coordinate X
**					VCoo_Y		- Virtual Coordinate Y
**
** Return:			RETSTAT		- RT_NORMAL	If Virtual Coord exist
**								- RT_FAILED	If Virtual Coord not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetZonePhisVirtCoordEx(float Coo_X, float Coo_Y, bool Virt, int *VCoo_X, int *VCoo_Y){
	RETCOND			stat;
	RETSTAT			retSt;
	FILEIDX			file;
	GENIDX			zoneIdx;
	t_cell			cell;
	int				j;
	float			AppX;
	float			AppY;

	*VCoo_X = 0;
	*VCoo_Y = 0;

	retSt = GetZoneIdxPhisCoo(Coo_X, Coo_Y, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	file.num = F_CE01 + zoneIdx - 1;

	for(j = 0; j < N_MAX_CELL; j++){
		stat = FileRead(&file, (j+1), 1, &cell, sizeof(t_cell));
		if(stat != RT_NORMAL)
			return(RT_FAILED);
        
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			break;

		AppX = (cell.Phys_X - Coo_X);
		if(AppX < 0.0)
			AppX =(float)(AppX * (-1.0));
		AppY = (cell.Phys_Y - Coo_Y);
		if(AppY < 0.0)
			AppY = (float)(AppY * (-1.0));

		if((AppX <= TOLL_MM) && (AppY <= TOLL_MM)){
			if(!Virt){
				*VCoo_X = (int)cell.Virt_X;
				*VCoo_Y = (int)cell.Virt_Y;
				return (RT_NORMAL);
			}
			else{
				if(cell.type == CELL_CORR_VIRT){
					*VCoo_X = (int)cell.Virt_X;
					*VCoo_Y = (int)cell.Virt_Y;
					return (RT_NORMAL);	
				}
			}
		}
	}

	return (RT_FAILED);
}
/*------------------------------------------------------------------------------
** Function:		GetZoneTVRotFree
**
** Description:		Get Virt. Coord. X & Y of nearest TV Free cell using Virt. Coord. X & Y
**
** Input:			VCoo_X		- Virtual Coordinate X
**					VCoo_Y		- Virtual Coordinate Y
**					TV_Angle    - if != -1.0: Look for this angle (altimenti va bene ogni cella con allowed rot.)
** Output:			VCoo_X		- Virtual Coordinate X of nearest ....
**					VCoo_Y		- Virtual Coordinate Y of nearest ....
**
** Return:			RETSTAT		- RT_NORMAL	If Virtual Coord exist
**								- RT_FAILED	If Virtual Coord not exist
** Modificata per utilizzo su NT.
** Modificata per la nuova struttura degli angoli di rotazione consentiti.
*/


/*RETSTAT GetZoneTVRotFree(int VCoo_X, int VCoo_Y,int *VCoo_X_TV, int *VCoo_Y_TV,
 						 float TV_Angle ){*/
RETSTAT GetZoneTVRotFree(int VCoo_X, int VCoo_Y,int *VCoo_X_TV, int *VCoo_Y_TV,
 						 float TV_Angle ){
	RETSTAT		stat;
	RETCOND		cond;
	t_cell		cell;
	GENIDX 		ZoneIdx;
	GENIDX 		ConfZoneIdx;
	t_cell		I_Cell;
	int			j;
	FILEIDX		file;
	float		Diff;
	float		App;
	float		App_X, App_Y;
	float		Pos_X, Pos_Y;
	float		TV_pos;
	int			NumConfZone;
	int			zz;
	int			App_VCoo_X_TV;
	int			App_VCoo_Y_TV;
	float		App_Diff;
	BOOL		Rot_possible;

	Rot_possible = false;
	*VCoo_X_TV = 0;
	*VCoo_Y_TV = 0;
	App_VCoo_X_TV = 0;
	App_VCoo_Y_TV = 0;
	
	//Prelevo la posizione attuale del TV-mast.//
	stat = Get_Mast_TV_Pos(&TV_pos);
	if ( stat != RT_NORMAL )
		return ( RT_FAILED );
	
	stat = GetZoneIdxVirtCoo ( VCoo_X, VCoo_Y, &ZoneIdx );
	if ( stat != RT_NORMAL )
		return ( RT_FAILED );
	
	stat = GetZoneVirtPar ( VCoo_X, VCoo_Y, &ZoneIdx, &I_Cell );
	if ( stat != RT_NORMAL )
		return ( RT_FAILED );

	Pos_X = I_Cell.Phys_X;
	Pos_Y = I_Cell.Phys_Y;

	Diff     = (float)999999.9;
	App_Diff = (float)999999.9;

	file.num = F_CE01 + (ZoneIdx-1);

	//Cerco prima nella zona della cella passata come parametro.//
	for ( j = 0; j < N_MAX_CELL; j++ ){
		cond = FileRead( &file, (j+1), 1, &cell, sizeof(t_cell) );
		if ( cond != R_NORMAL )
			return (RT_FAILED);
        if ( ( cell.Virt_X == 0 ) && ( cell.Virt_Y == 0 ) )
			break;

		if ( cell.Rot_Flag == ROT_ALLOWED ){
			App_X = (cell.Phys_X - Pos_X) * (cell.Phys_X - Pos_X);
			App_Y = (cell.Phys_Y - Pos_Y) * (cell.Phys_Y - Pos_Y);
			App = (float)sqrt(App_X + App_Y);
			
			//Se la distanza della cella � minore delle precedenti, allora controllo se
			//posso eseguire una rotazione per passare dall'angolo in cui si trova il
			//TV-mast all'angolo finale richiesto.//
			if (App < App_Diff){
				//CheckRot
				
				
				App_Diff = App;
				App_VCoo_X_TV = (int)cell.Virt_X;
				App_VCoo_Y_TV = (int)cell.Virt_Y;
			}
			//Dopo aver trovato la zona con distanza minore dove sia consentita la rotazine
			// controlla gli angoli consentiti.
			// Apportare modifiche per la variazione della struttura degli angoli._RETMOD_//
		/*	  if ( ((TV_Angle == -1.0) && (App < Diff)) ||
				   ((TV_Angle != -1.0) && (App < Diff) && (TV_Angle == cell.Tv_Angle)) )
			   {
				Diff = App;

				*VCoo_X_TV = (int)cell.Virt_X;
				*VCoo_Y_TV = (int)cell.Virt_Y;
			   }*/
			if(((TV_Angle == -1.0) && (App < Diff)) || ((TV_Angle != -1.0) && (App < Diff) && (CheckCellAllTVAngle((int)TV_Angle, cell.Virt_X, cell.Virt_Y) == RT_NORMAL)) ){
				Diff = App;
				*VCoo_X_TV = (int)cell.Virt_X;
				*VCoo_Y_TV = (int)cell.Virt_Y;
			}
		}
	}//end for

  if ( ( *VCoo_X_TV == 0 ) || ( *VCoo_Y_TV == 0 ) ){
		if ( ( App_VCoo_X_TV != 0 ) && ( App_VCoo_Y_TV != 0 ) ){
			  *VCoo_X_TV = App_VCoo_X_TV;
			  *VCoo_Y_TV = App_VCoo_Y_TV;
			  return (RT_NORMAL);
		}
   }
  else
		return (RT_NORMAL);

  /* ** *** ****** ***** ***** **** ********** */
  /* SE NON TROVO, CERCO NELLE ZONE CONFINANTI */
  /* ** *** ****** ***** ***** **** ********** */

  stat = GetZoneNumConfZone ( ZoneIdx, &NumConfZone );
  if ( stat != RT_NORMAL )
		return (RT_FAILED);

  for ( zz = 1; zz <= NumConfZone; zz ++ )
   {
    stat = GetZoneConfZoneIdx	( ZoneIdx, zz, &ConfZoneIdx );
    if ( stat != RT_NORMAL )
      return (RT_FAILED);
      
    file.num = F_CE01 + (ConfZoneIdx-1);

    for ( j = 0; j < N_MAX_CELL; j++ )
     {
      cond = FileRead( &file, (j+1), 1, &cell, sizeof(t_cell) );
      if ( stat != R_NORMAL )
        return (RT_FAILED);
        
      if ( ( cell.Virt_X == 0 ) &&
	   ( cell.Virt_Y == 0 ) )
        break;

      if ( cell.Rot_Flag == ROT_ALLOWED )
       {
        if ( Pos_X > cell.Phys_X )
          App_X = Pos_X - cell.Phys_X;
        else
          App_X = cell.Phys_X - Pos_X;

        if ( Pos_Y > cell.Phys_Y )
          App_Y = Pos_Y - cell.Phys_Y;
        else
          App_Y = cell.Phys_Y - Pos_Y;

        App = App_X + App_Y;

        if ( App < App_Diff )
         {
          App_Diff = App;

          App_VCoo_X_TV = (int)cell.Virt_X;
          App_VCoo_Y_TV = (int)cell.Virt_Y;
         }
// Apportare modifiche per la variazione della struttura degli angoli._RETMOD_//
/*        if ( ((TV_Angle == -1.0) && (App < Diff)) ||
           ((TV_Angle != -1.0) && (App < Diff) && (TV_Angle == cell.Tv_Angle)) )
         {
          Diff = App;

          *VCoo_X_TV = (int)cell.Virt_X;
          *VCoo_Y_TV = (int)cell.Virt_Y;
         }*/
       if(((TV_Angle == -1.0) && (App < Diff)) || ((TV_Angle != -1.0) && (App < Diff) && (CheckCellAllTVAngle((int)TV_Angle, cell.Virt_X, cell.Virt_Y) == RT_NORMAL)) ){
				Diff = App;

				*VCoo_X_TV = (int)cell.Virt_X;
				*VCoo_Y_TV = (int)cell.Virt_Y;
			  }
	  }
     }

    if ( ( *VCoo_X_TV == 0 ) || ( *VCoo_Y_TV == 0 ) )
     {
      if ( ( App_VCoo_X_TV != 0 ) && ( App_VCoo_Y_TV != 0 ) )
       {
        *VCoo_X_TV = App_VCoo_X_TV;
        *VCoo_Y_TV = App_VCoo_Y_TV;
        return (RT_NORMAL);
       }
     }
    else
      return (RT_NORMAL);
   }

  if ( ( *VCoo_X_TV == 0 ) || ( *VCoo_Y_TV == 0 ) )
    return (RT_FAILED);

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNearCell
**
** Description:		Get Virt. Coord. X & Y and Flag Rotation
**					of nearest cell using Phisyc. Coord. X & Y
**
** Input:			Coo_X		- Phisycal Coordinate X
**					Coo_Y		- Phisycal Coordinate Y
**					moveTo		- Move to cell flag
** Output:			VCoo_X		- Virtual Coordinate X of nearest ....
**					VCoo_Y		- Virtual Coordinate Y of nearest ....
**					Rot_Flag	- Rotation Allowed Flag
**					TV_range	- TV Angle Rotation ranges 
**
** Return:			RETSTAT		- RT_NORMAL	If Virtual Coord exist
**								- RT_FAILED	If Virtual Coord not exist
** Modificata per utilizzo su NT.
** Modificata per introduzione nuova struttura dati per gli angoli.
*/
RETSTAT GetZoneNearCell(float Coo_X, float Coo_Y, int *VCoo_X, int *VCoo_Y,
						int *Rot_Flag, TV_angle *TV_range, bool moveTo){
	RETSTAT		stat;
	RETCOND		cond;
	PHASTAT		retPh;
	t_cell		cell;
	GENIDX 		ZoneIdx;
	int			i, j;
	int			cont;
	int			startRec;
	int			stopRec;
	FILEIDX		file;
	float		Diff;
	float		App;
	float		App_X, App_Y;
	float		Pos_X, Pos_Y;
	OBJTMM		temp;
	GENIDX		zoneIdx;
	GENIDX		zoneIOIdx;
	int			virtFlag;
	bool		seek;
	
	*VCoo_X = 0;
	*VCoo_Y = 0;
	*Rot_Flag = ROT_NOT_ALLOWED;
	TV_range->range_1[0] = -1;
	TV_range->range_1[1] = -1;
	TV_range->range_2[0] = -1;
	TV_range->range_2[1] = -1;

	startRec = 0;
	stopRec = 0;

	seek = false;

	GetZoneIdx(ZONE_IO, &zoneIOIdx);
	stat = GetZoneIdxPhisCoo(Coo_X, Coo_Y, &ZoneIdx);
	if(stat != RT_NORMAL)
		seek = true;
	
	stat = IsVirtualZoneIdx(ZoneIdx, &virtFlag);
	if(stat != RT_NORMAL)
		return(RT_FAILED);

	if((seek) || (virtFlag == 1)){
		Pos_X = Coo_X;
		Pos_Y = Coo_Y;

		Diff = (float)999999.9;

		for(i = 1; i <= N_MAX_ZONE; i++){
			
			if(i == 1){
				GetDynCurrentCont(&cont);
				if(cont == Z1_CONT_TK13){
					startRec = 1;
					stopRec = CONT_TK13_CELLS;
				}
				else if(cont == Z1_CONT_LOAD){
					startRec = CONT_TK13_CELLS + 1;
					stopRec = CONT_TK13_CELLS + CONT_LOAD_CELLS;
				}	
				else if(cont == Z1_CONT_HECA){
					startRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + 1;
					stopRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + CONT_HECA_CELLS;
				}
				else{
					startRec = N_MAX_CELL;
					stopRec = N_MAX_CELL;
				}
			}else{
				startRec = 1;
				stopRec = N_MAX_CELL;
			}

			file.num = F_CE01 + (i - 1);

			for(j = 1; j <= N_MAX_CELL; j++){
				cond = FileRead( &file, j, 1, &cell, sizeof(t_cell) );
				if ( cond != R_NORMAL )
					return (RT_FAILED);
				if ( ( cell.Virt_X == 0 ) && ( cell.Virt_Y == 0 ) )
					continue;

				if(((j < startRec) || (j > stopRec)) && (cell.type != CELL_CORR_VIRT))
					continue;

				App_X = (cell.Phys_X - Pos_X) * (cell.Phys_X - Pos_X);
				App_Y = (cell.Phys_Y - Pos_Y) * (cell.Phys_Y - Pos_Y);
				App =(float)(sqrt(App_X + App_Y));
				if ( App < Diff ){
					Diff = App;
					*VCoo_X = (int)cell.Virt_X;
					*VCoo_Y = (int)cell.Virt_Y;
					*Rot_Flag = cell.Rot_Flag;
					TV_range->range_1[0] = cell.Rot_Range.range_1[0];
					TV_range->range_1[1] = cell.Rot_Range.range_1[1];
					TV_range->range_2[0] = cell.Rot_Range.range_2[0];
					TV_range->range_2[1] = cell.Rot_Range.range_2[1];
				}
			}
		}
		if ( ( *VCoo_X == 0 ) || ( *VCoo_Y == 0 ) )
			return (RT_FAILED);
		else{
			stat = GetMastSituation(&temp);
			stat = GetZoneVirtPar(*VCoo_X, *VCoo_Y, &zoneIdx, &cell);
			if(stat != RT_NORMAL)
				return(stat);
			if(moveTo){
				retPh = Mov_xy_Exec(zoneIdx, Coo_X, cell.Phys_X, Coo_Y, cell.Phys_Y);
				if(retPh != PH_NORMAL)
					return(RT_FAILED);
			}
		}
		return (RT_NORMAL);
	}
	else{
		Pos_X = Coo_X;
		Pos_Y = Coo_Y;

		Diff = (float)999999.9;

		file.num = F_CE01 + (ZoneIdx-1);

		if(ZoneIdx == zoneIOIdx){
			GetDynCurrentCont(&cont);
			if(cont == Z1_CONT_TK13){
				startRec = 1;
				stopRec = CONT_TK13_CELLS;
			}
			else if(cont == Z1_CONT_LOAD){
				startRec = CONT_TK13_CELLS + 1;
				stopRec = CONT_TK13_CELLS + CONT_LOAD_CELLS;
			}	
			else if(cont == Z1_CONT_HECA){
				startRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + 1;
				stopRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + CONT_HECA_CELLS;
			}
			else{
				startRec = N_MAX_CELL;
				stopRec = N_MAX_CELL;
			}		
		}
		else{
			startRec = 1;
				stopRec = N_MAX_CELL;
		}

		for ( j = 1; j <= N_MAX_CELL; j++ ){
			cond = FileRead(&file, j, 1, &cell, sizeof(t_cell));
			if(cond != R_NORMAL)
				return (RT_FAILED);
			if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
				continue;

			if(((j < startRec) || (j >= stopRec)) && (cell.type != CELL_CORR_VIRT))
				continue;

			App_X = (cell.Phys_X - Pos_X) * (cell.Phys_X - Pos_X);
			App_Y = (cell.Phys_Y - Pos_Y) * (cell.Phys_Y - Pos_Y);
			App =(float)(sqrt(App_X + App_Y));
			if ( App < Diff ){
				Diff = App;
				*VCoo_X = (int)cell.Virt_X;
				*VCoo_Y = (int)cell.Virt_Y;
				*Rot_Flag = cell.Rot_Flag;
				// Apportare modifiche per la variazione della struttura degli angoli._RETMOD_//
				//      *TV_Angle = cell.Tv_Angle;
				TV_range->range_1[0] = cell.Rot_Range.range_1[0];
				TV_range->range_1[1] = cell.Rot_Range.range_1[1];
				TV_range->range_2[0] = cell.Rot_Range.range_2[0];
				TV_range->range_2[1] = cell.Rot_Range.range_2[1];
			}
		}
		if ( ( *VCoo_X == 0 ) || ( *VCoo_Y == 0 ) )
			return (RT_FAILED);
		else{
			stat = GetMastSituation(&temp);
			stat = GetZoneVirtPar(*VCoo_X, *VCoo_Y, &zoneIdx, &cell);
			if(stat != RT_NORMAL)
				return(stat);
			if(moveTo){
				retPh = Mov_xy_Exec(zoneIdx, Coo_X, cell.Phys_X, Coo_Y, cell.Phys_Y);
				if(retPh != PH_NORMAL)
					return(RT_FAILED);
			}
		}
		return (RT_NORMAL);
	}
}

/*------------------------------------------------------------------------------
** Function:		GetZoneRadiusCenter
**
** Description:		Get Zone (Only for Reactor) Radius and Center using Zone Idx
**
** Input:			ZoneIdx		- Zone Idx
**
** Output:			Radius		- Radius of Zone
**					Center_X	- X Coord. of Center of Zone
**					Center_Y	- Y Coord. of Center of Zone
**
** Return:			RETSTAT		- RT_NORMAL	If operation OK
**								- RT_FAILED	If operation KO
**								- RT_INVZONE If zone !Z4 & Z3
** Modificata per utilizzo su NT.
** Permetto l'operazione solo sulle zone Z3 (scarico) e Z4 (reattore).
*/

RETSTAT GetZoneRadiusCenter	( GENIDX ZoneIdx, float *Radius,
					float *Center_X, float *Center_Y )
{
  RETSTAT	retstat;
  float		L_H_CooX, L_H_CooY, R_L_CooX, R_L_CooY;
  ZONENAME	tempName;

  retstat = GetZoneName(ZoneIdx, tempName);
  if ( retstat != RT_NORMAL )
    return ( retstat );

  if((_tcscmp(tempName, _T("Z3")) != 0) && (_tcscmp(tempName, _T("Z4")) != 0))
	  return(RT_INVZONE);

  *Radius = -1;
  *Center_X = -1;

  retstat = GetZoneCoord ( ZoneIdx, &L_H_CooX, &L_H_CooY, &R_L_CooX, &R_L_CooY );
  if ( retstat != RT_NORMAL )
    return ( retstat );

  if ( ( L_H_CooX - R_L_CooX ) != ( L_H_CooY - R_L_CooY ) )
    return (RT_FAILED);

  *Radius = (L_H_CooX - R_L_CooX) / 2;

  *Center_X = ( R_L_CooX + *Radius );
  *Center_Y = ( R_L_CooY + *Radius );

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		PutZoneVirtPar
**
** Description:		Put Virtual Parameters using Virtual Coord. X & Y
**
** Input:			VCoo_X		- Virtual Coordinate X
**					VCoo_Y		- Virtual Coordinate Y
**					Cell		- Cell Virtual Parameters
** Output:
**
** Return:			RETSTAT		- RT_NORMAL	If Put operation OK
**								- RT_FAILED	If Virtual Coord. NOT exist
** Modificata per utilizzo su NT.
*/	

RETSTAT PutZoneVirtPar(int VCoo_X, int VCoo_Y, t_cell *Cell){
	RETCOND	stat;
	t_cell	cell;
	int		j;
	FILEIDX	file;
	GENIDX	zoneIdx;

	GetZoneIdxVirtCoo(VCoo_X, VCoo_Y, &zoneIdx);

//  for ( i = 0; i < N_MAX_ZONE; i++ )
//   {
	file.num = F_CE01 + zoneIdx - 1;
    for (j = 0; j < N_MAX_CELL; j++){
		stat = FileRead( &file, (j+1), 1, &cell, sizeof(t_cell));
		 if ( stat != RT_NORMAL )
			return (RT_FAILED);
        
		 if ( ( cell.Virt_X == 0 ) && ( cell.Virt_Y == 0 ) )
			break;

		if ( ( cell.Virt_X == VCoo_X ) && ( cell.Virt_Y == VCoo_Y ) ){
			stat = FileWrite( &file, (j+1), 1, Cell, sizeof(t_cell) );
			return (RT_NORMAL);
		}
     }
//   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtName
**
** Description:		Get Object Type Name using Object Type Idx
**
** Input:			ObjtIdx		- Object Type Idx
** Output:			ObjtName	- Object Type Name
**
** Return:			RETSTAT		- RT_NORMAL	If Object Type exist
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtName		( GENIDX ObjtIdx, OBJTNAME ObjtName )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  ObjtName[0] = '\0';

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

//  StringFill ( objt.name, (L_OBJT_NAM + 1) );
  _tcsncpy_s(ObjtName,sizeof(ObjtName), objt.name, L_OBJT_NAM );
  ObjtName[L_OBJT_NAM] = '\0';

  return (RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		GetObjtIdx
**
** Description:		Get Object Type Idx using Object Type Name
**
** Input:			ObjtName	- Object Type Name
** Output:			ObjtIdx		- Object Type Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Object Type exist
**								- RT_INVOBJT	If invalid Object Type Name
**								- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtIdx		( OBJTNAME ObjtName, GENIDX *ObjtIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *ObjtIdx = (GENIDX)0;

  if ( !_tcscmp( ObjtName, _T("") ) )
    return (RT_INVOBJT);

//  StringFill ( ObjtName, (L_OBJT_NAM + 1) );

  for ( i = 0; i < N_MAX_OBJT; i++ )
   {
    stat = FileRead(&file, (i+1), 1, &objt, sizeof(t_obj_type) );

//    StringFill ( objt.name, (L_OBJT_NAM + 1) );
    if ( !_tcsncmp ( ObjtName, objt.name, L_OBJT_NAM ) )
     {
      *ObjtIdx = (GENIDX)(i+1);
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtIdxGeneric
**
** Description:		Get Object Type Idx using Object Type Name
**
** Input:			ObjtGenericName		- Generic Object Type Name
** Output:			ObjtIdx				- Object Type Idx
**
** Return:			RETSTAT				- RT_NORMAL	If Object Type exist
**										- RT_INVOBJT	If invalid Generic Object Type Name 
**										- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtIdxGeneric	( OBJTNAME ObjtGenericName, GENIDX *ObjtIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *ObjtIdx = (GENIDX)0;

  if ( !_tcscmp( ObjtGenericName, _T("") ) )
    return (RT_INVOBJT);

//  StringFill ( ObjtGenericName, (L_OBJT_NAM + 1) );

  for ( i = 0; i < N_MAX_OBJT; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &objt, sizeof(t_obj_type) );

//    StringFill ( objt.obj_phase, (L_OBJT_NAM + 1) );
    if ( !_tcsncmp ( ObjtGenericName, objt.obj_phase, L_OBJT_NAM ) )
     {
      *ObjtIdx = (GENIDX)(i+1);
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtDimensions
**
** Description:		Get Object Type Dimensions using Object Type Idx
**
** Input:			ObjtIdx		- Object Type Idx
** Output:			DimX		- Object Type X Dimension
**					DimY		- Object Type Y Dimension
**					DimZ		- Object Type Z Dimension
**
** Return:			RETSTAT		- RT_NORMAL	If Object Type exist
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
** I dati degli oggetti per ora non prevedono tre dimensioni.
** Sulla X c'� la lunghezza, sulla Y il peso dell'oggetto.
** La z non viene prelevata.
*/

RETSTAT GetObjtDimensions	( GENIDX ObjtIdx, float *DimX, float *DimY, float *DimZ )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *DimX = 0.0;
  *DimY = 0.0;
  *DimZ = 0.0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *DimX = objt.obj_dim.x;
  *DimY = objt.obj_dim.y;
  *DimZ = objt.obj_dim.z;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtDescription
**
** Description:		Get Object Type Description using Object Type Idx
**
** Input:			ObjtIdx		- Object Type Idx
** Output:			Descr		- Object Type Description
**
** Return:			RETSTAT		- RT_NORMAL	If Object Type exist
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
** I dati degli oggetti per ora non prevedono tre dimensioni.
** Sulla X c'� la lunghezza, sulla Y il peso dell'oggetto.
** La z non viene prelevata.
*/

RETSTAT GetObjtDescription	( GENIDX ObjtIdx, TCHAR *Descr)
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  _stprintf_s(Descr,sizeof(Descr), _T(""));

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  _stprintf_s(Descr,sizeof(Descr), _T("%s"), objt.obj_descr);

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtGenericType
**
** Description:		Get Generic Object Type Name using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
** Output:			ObjtGeneric		- Generic Object Type Name
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtGenericType	( GENIDX ObjtIdx, OBJTNAME ObjtGeneric )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  ObjtGeneric[0] = '\0';

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

//  StringFill ( objt.obj_phase, (L_OBJT_NAM + 1) );
  _tcsncpy_s( ObjtGeneric,sizeof(ObjtGeneric), objt.obj_phase, L_OBJT_NAM );
  ObjtGeneric[L_OBJT_NAM] = '\0';

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtGenericTypeCode
**
** Description:		Get Generic Object Type Code using Object Type Idx
**
** Input:			ObjtIdx		- Object Type Idx
** Output:			ObjtGenCode	- Generic Object Type Code
**
** Return:			RETSTAT		- RT_NORMAL	If Object Type exist
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtGenericTypeCode	( GENIDX ObjtIdx, int *ObjtGenCode )
{
  RETCOND		stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *ObjtGenCode = OBJT_N_KO;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

//  StringFill ( objt.obj_phase, (L_OBJT_NAM + 1) );

  if ( !_tcsncmp ( OBJT_FA, objt.obj_phase, L_OBJT_NAM ) )
   {
    *ObjtGenCode = OBJT_N_FA;
    return (RT_NORMAL);
   }

  if ( !_tcsncmp ( OBJT_CLUS, objt.obj_phase, L_OBJT_NAM ) )
   {
	*ObjtGenCode = OBJT_N_CLUS;
    return (RT_NORMAL);
   }

  if ( !_tcsncmp ( OBJT_HECA, objt.obj_phase, L_OBJT_NAM ) )
   {
    *ObjtGenCode = OBJT_N_HECA;
    return (RT_NORMAL);
   }

  if ( !_tcsncmp ( OBJT_HECA_COV, objt.obj_phase, L_OBJT_NAM ) )
   {
    *ObjtGenCode = OBJT_N_COVER;
    return (RT_NORMAL);
   }

  if ( !_tcsncmp ( OBJT_CLUS_CAS, objt.obj_phase, L_OBJT_NAM ) )
   {
    *ObjtGenCode = OBJT_N_CLUS_CAS;
    return (RT_NORMAL);
   }

  if ( !_tcsncmp ( OBJT_CLUS_FRM, objt.obj_phase, L_OBJT_NAM ) )
   {
    *ObjtGenCode = OBJT_N_CLUS_FRM;
    return (RT_NORMAL);
   }

  if ( !_tcsncmp ( OBJT_FFDS_COV, objt.obj_phase, L_OBJT_NAM ) )
   {
    *ObjtGenCode = OBJT_N_FFDS_COV;
    return (RT_NORMAL);
   }

  
  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtNumLegalSource
**
** Description:		Get Number of Legal Source Zone using Object Type Idx
**
** Input:			ObjtIdx	- Object Type Idx
** Output:			NumLegalSource- Number of Legal Sources for Object Type
**
** Return:			RETSTAT	- RT_NORMAL	If Object Type exist
**							- RT_INVOBJT	If invalid Object Type Idx
**							- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtNumLegalSource	( GENIDX ObjtIdx, int *NumLegalSource )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *NumLegalSource = 0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *NumLegalSource = objt.n_sour_zone;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtLegalSourceIdx
**
** Description:		Get Idx of Legal source Zone using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
**					NumLegalSource	- Legal Source Zone Index
** Output:			LegalSourceIdx	- Idx of Legal Source Zone
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_INVSOUR	If invalid Source Zone Index
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtLegalSourceIdx	( GENIDX ObjtIdx, int NumLegalSource,
					GENIDX *LegalSourceIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *LegalSourceIdx = (GENIDX)0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  if ( ( NumLegalSource <= 0 ) || ( NumLegalSource > N_MAX_ZONE ) )
    return (RT_INVSOUR);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *LegalSourceIdx = (GENIDX)objt.sour_zone[NumLegalSource-1];

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtNumLegalDest
**
** Description:		Get Number of Legal Destination Zone using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
** Output:			NumLegalDest	- Number of Legal Destination for Object Type
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtNumLegalDest	( GENIDX ObjtIdx, int *NumLegalDest )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *NumLegalDest = 0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *NumLegalDest = objt.n_dest_zone;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtLegalDestIdx
**
** Description:		Get Idx of Legal Destination Zone using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
**					NumLegalDest	- Legal Destination Zone Index
** Output:			LegalDestIdx	- Idx of Legal Destination Zone
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_INVDEST	If invalid Dest. Zone Index
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtLegalDestIdx	( GENIDX ObjtIdx, int NumLegalDest,
					GENIDX *LegalDestIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *LegalDestIdx = (GENIDX)0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  if ( ( NumLegalDest <= 0 ) || ( NumLegalDest > N_MAX_ZONE ) )
    return (RT_INVDEST);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *LegalDestIdx = (GENIDX)objt.dest_zone[NumLegalDest-1];

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtNumLegalObject
**
** Description:		Get Number of Legal Composed Object using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
** Output:			NumLegalObject	- Number of Legal Comp. Object for Object Type
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_FAILED	If Object Type not exist
**
** Modificata per utilizzo su NT.*/

RETSTAT GetObjtNumLegalObject	( GENIDX ObjtIdx, int *NumLegalObject )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *NumLegalObject = 0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *NumLegalObject = objt.n_legal_obj;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtLegalObjectIdx
**
** Description:		Get Idx of Legal Composed Object using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
**					NumLegalObject	- Legal Composed Object Index
** Output:			LegalObjectIdx	- Idx of Legal Composed Object
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_INVCOMP	If invalid Comp. Object Index
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtLegalObjectIdx	( GENIDX ObjtIdx, int NumLegalObject,
					GENIDX *LegalObjectIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *LegalObjectIdx = (GENIDX)0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  if ( ( NumLegalObject <= 0 ) || ( NumLegalObject > N_MAX_OBJT ) )
    return (RT_INVCOMP);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type)  );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *LegalObjectIdx = (GENIDX)objt.legal_obj[NumLegalObject-1];

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtNumLegalContain
**
** Description:		Get Number of Legal Container using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
** Output:			NumLegalContain	- Number of Legal Container
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtNumLegalContain	( GENIDX ObjtIdx, int *NumLegalContain )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *NumLegalContain = 0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *NumLegalContain = objt.n_cont_req;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtLegalContainIdx
**
** Description:		Get Idx of Legal Container using Object Type Idx
**
** Input:			ObjtIdx			- Object Type Idx
**					NumLegalContain	- Legal Container Index
** Output:			LegalContainIdx	- Idx of legal Container
**
** Return:			RETSTAT			- RT_NORMAL	If Object Type exist
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_INVCONT	If invalid Container Index
**									- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjtLegalContainIdx	( GENIDX ObjtIdx, int NumLegalContain,
					GENIDX *LegalContainIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *LegalContainIdx = (GENIDX)0;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

/***********************************************************************
  if ( ( NumLegalContain <= 0 ) || ( NumLegalContain > N_MAX_CONT ) )
    return (RT_INVCONT);
***********************************************************************/

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  *LegalContainIdx = (GENIDX)objt.cont_req[NumLegalContain-1];

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjName
**
** Description:		Get Object Name using Object Idx
**
** Input:			ObjIdx		- Object Idx
** Output:			ObjName		- Object Name
**
** Return:			RETSTAT		- RT_NORMAL	If Object exist
**								- RT_INVOBJ	If invalid Object Idx
**								- RT_FAILED	If Object not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjName		( GENIDX ObjectIdx, OBJNAME ObjectName )
{
  RETCOND	stat;
  t_obj		obj;
//  int		i;
  FILEIDX	file;

  ObjectName[0] = '\0';
  file.num = F_OBJE;
  
  if ( ( ObjectIdx <= 0 ) || ( ObjectIdx > N_MAX_OBJ ) )
    return (RT_INVOBJ);

  stat = FileRead( &file, ObjectIdx, 1, &obj, sizeof(t_obj) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJ);

  if ( !_tcscmp( obj.name, _T("") ) )
    return (RT_FAILED);

//  StringFill ( obj.name, (L_OBJ_NAME + 1) );
  _tcsncpy_s(ObjectName,sizeof(ObjectName), obj.name, L_OBJ_NAME );
  ObjectName[L_OBJ_NAME] = '\0';

  return (RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		GetObjIdx
**
** Description:		Get Object Idx using Object Name
**
** Input:			ObjName		- Object Name
** Output:			ObjectIdx	- Object Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Object exist
**								- RT_INVOBJ	If invalid Object Name
**								- RT_FAILED	If Object not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjIdx		( OBJNAME ObjectName, GENIDX *ObjectIdx )
{
  RETCOND	stat;
  t_obj		obj;
  int		i;
  FILEIDX	file;

  file.num = F_OBJE;

  *ObjectIdx = (GENIDX)0;

  if ( !_tcscmp( ObjectName, _T("") ) )
    return (RT_INVOBJ);

//  StringFill ( ObjectName, (L_OBJ_NAME + 1) );

  for ( i = 0; i < N_MAX_OBJ; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &obj, sizeof(t_obj) );

//    StringFill ( obj.name, (L_OBJ_NAME + 1) );
    if ( !_tcsncmp ( ObjectName, obj.name, L_OBJ_NAME ) )
     {
      *ObjectIdx = (GENIDX)(i+1);
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetObjObjtIdx
**
** Description:		Get Object Type Idx using Object Idx
**	
** Input:			ObjectIdx	- Object Idx
** Output:			ObjtIdx		- Object Type Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Object exist
**								- RT_INVOBJ	If invalid Object Idx
**								- RT_FAILED	If Object not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetObjObjtIdx		( GENIDX ObjectIdx, GENIDX *ObjtIdx )
{
  RETCOND	stat;
  t_obj		obj;
//  int		i;
  FILEIDX	file;

  file.num = F_OBJE;

  *ObjtIdx = (GENIDX)0;

  if ( ( ObjectIdx <= 0 ) || ( ObjectIdx > N_MAX_OBJ ) )
    return (RT_INVOBJ);

  stat = FileRead( &file, (int)ObjectIdx, 1, &obj, sizeof(t_obj));
  if ( stat != R_NORMAL )
    return (RT_INVOBJ);

  if ( !_tcscmp( obj.name, _T("") ) )
    return (RT_FAILED);

  *ObjtIdx = obj.obj_type;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		PutObjObjtIdx
**	
** Description:		Put Object Type Idx using Object Idx
**
** Input:			ObjectIdx	- Object Idx
** Output:			ObjtIdx		- Object Type Idx
**
** Return:			RETSTAT		- RT_NORMAL	If operation Ok
**								- RT_INVOBJ	If invalid Object Idx
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If operation Ko
** Modificata per utilizzo su NT.
*/

RETSTAT PutObjObjtIdx		( GENIDX ObjectIdx, GENIDX ObjtIdx )
{
  RETCOND	stat;
  t_obj		obj;
//  int		i;
  FILEIDX file;

  file.num = F_OBJE;

  if ( ( ObjectIdx <= 0 ) || ( ObjectIdx > N_MAX_OBJ ) )
    return (RT_INVOBJ);

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjectIdx, 1, &obj, sizeof(t_obj) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJ);

  obj.obj_type = ObjtIdx;

  stat = FileWrite( &file, (int)ObjectIdx, 1, &obj, sizeof(t_obj));
  if ( stat != R_NORMAL )
    return (RT_INVOBJ);

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetContainName
**
** Description:		Get Container Name using Container Idx
**
** Input:			ContainIdx		- Container Idx
** Output:			ContainName		- Container Name
**
** Return:			RETSTAT			- RT_NORMAL		If Container exist
**									- RT_INVCONT	If invalid Container Idx
**									- RT_FAILED		If Container not exist
*/

RETSTAT GetContainName(GENIDX ContainIdx, CONTNAME ContainName){
	ContainName[0] = '\0';

	if ((ContainIdx < 0) || (ContainIdx > N_MAX_CONT))
		return (RT_INVCONT);

	if (ContainIdx == Z1_CONT_TK13){
		_tcsncpy_s(ContainName,sizeof(ContainName), Z1_CONT_TK13_N, L_CONT_NAME );
		ContainName[L_CONT_NAME] = '\0';
		return(RT_NORMAL);
	}
	else if (ContainIdx == Z1_CONT_HECA){
		_tcsncpy_s(ContainName,sizeof(ContainName), Z1_CONT_HECA_N, L_CONT_NAME );
		ContainName[L_CONT_NAME] = '\0';
		return(RT_NORMAL);
	}
	else if (ContainIdx == Z1_CONT_LOAD){
		_tcsncpy_s(ContainName,sizeof(ContainName), Z1_CONT_LOAD_N, L_CONT_NAME );
		ContainName[L_CONT_NAME] = '\0';
		return(RT_NORMAL);
	}
	else if (ContainIdx == Z1_NO_CONT){
		_tcsncpy_s(ContainName,sizeof(ContainName), Z1_CONT_NOCON_N, L_CONT_NAME );
		ContainName[L_CONT_NAME] = '\0';
		return(RT_NORMAL);
	}
	return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetContainIdx
**
** Description:		Get Container Idx using Container Name 
**
** Input:			ContainName		- ContainerName
** Output:			ContainIdx		- Container Idx
**
** Return:			RETSTAT			- RT_NORMAL		If Container exist
**									- RT_INVCONT	If invalid Container Name
**									- RT_FAILED		If Container not exist
*/

RETSTAT GetContainIdx(CONTNAME *ContainName, GENIDX *ContainIdx){
	*ContainIdx = (GENIDX)0;

	if (!_tcscmp(*ContainName, _T("")))
		return (RT_INVCONT);

    if (!_tcsncmp (*ContainName, Z1_CONT_TK13_N, L_CONT_NAME)){
		*ContainIdx = (GENIDX)(Z1_CONT_TK13);
		return (RT_NORMAL);
    }
	else if (!_tcsncmp(*ContainName, Z1_CONT_HECA_N, L_CONT_NAME)){
		*ContainIdx = (GENIDX)(Z1_CONT_HECA);
		return (RT_NORMAL);
    }
	else if (!_tcsncmp(*ContainName, Z1_CONT_LOAD_N, L_CONT_NAME)){
		*ContainIdx = (GENIDX)(Z1_CONT_LOAD);
		return (RT_NORMAL);
    }
	else if (!_tcsncmp(*ContainName, Z1_CONT_NOCON_N, L_CONT_NAME)){
		*ContainIdx = (GENIDX)(Z1_NO_CONT);
		return (RT_NORMAL);
    }
   
	return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMacroCmdName
**
** Description:		Get Macro Command Name using Macro Command Idx
**
** Input:			MacroCdmIdx		- Macro Cmd Idx
** Output:			MacroCmdName	- Macro Cmd Name
**
** Return:			RETSTAT			- RT_NORMAL	If Macro Command exist
**									- RT_INVMACC	If Macro Command Idx
**									- RT_FAILED	If Macro Command not exist
*/

RETSTAT GetMacroCmdName		( GENIDX MacroCmdIdx, MAC_CMDNAME MacroCmdName )
{
  RETCOND	stat;
  t_macro_cmd	macro;
//  int		i;
  FILEIDX	file;

  file.num = F_MACR;

  MacroCmdName[0] = '\0';

  if ( ( MacroCmdIdx <= 0 ) || ( MacroCmdIdx > N_MAX_MAC_CMD ) )
    return (RT_INVMACC);

  stat = FileRead( &file, (int)MacroCmdIdx, 1, &macro ,sizeof(t_macro_cmd));
  if ( stat != R_NORMAL )
    return (RT_INVMACC);

  if ( !_tcscmp( macro.name, _T("") ) )
    return (RT_FAILED);

//  StringFill ( macro.name, (L_MAC_CMD + 1) );
  _tcsncpy_s(MacroCmdName,sizeof(MacroCmdName), macro.name, L_MAC_CMD );
  MacroCmdName[L_MAC_CMD] = '\0';

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMacroCmdIdx
**
** Description:		Get Macro Command Idx using Macro Command Name
**
** Input:			MacroCmdName	- Macro Command Name
** Output:			MacroCmdIdx		- Macro Command Idx
**
** Return:			RETSTAT			- RT_NORMAL	If Macro Command exist
**									- RT_INVMACC	If invalid Macro Command Name
**									- RT_FAILED	If Macro Command not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetMacroCmdIdx		( MAC_CMDNAME MacroCmdName, GENIDX *MacroCmdIdx )
{
  RETCOND	stat;
  t_macro_cmd	macro;
  int		i;
  FILEIDX	file;

  file.num = F_MACR;

  *MacroCmdIdx = (GENIDX)0;

  if ( !_tcscmp( MacroCmdName, _T("") ) )
    return (RT_INVMACC);

//  StringFill ( MacroCmdName, (L_MAC_CMD + 1) );

  for ( i = 0; i < N_MAX_MAC_CMD; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &macro, sizeof(t_macro_cmd) );

//    StringFill ( macro.name, (L_MAC_CMD + 1) );
    if ( !_tcsncmp ( MacroCmdName, macro.name, L_MAC_CMD ) )
     {
      *MacroCmdIdx = (GENIDX)(i+1);
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMacroNumLegalObject
**
** Description:		Get Number of Legal Object using Macro Command Idx
**
** Input:			MacroCmdIdx		- Macro Command Idx
** Output:			NumLegalObject	- Number of Legal Object for Macro Command
**
** Return:			RETSTAT			- RT_NORMAL	If Macro Command exist
**									- RT_INVMACC	If invalid Macro Command Idx
**									- RT_FAILED	If Macro Command not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetMacroNumLegalObject	( GENIDX MacroCmdIdx, int *NumLegalObject )
{
  RETCOND	stat;
  t_macro_cmd	macro;
//  int		i;
  FILEIDX	file;

  file.num = F_MACR;

  *NumLegalObject = 0;

  if ( ( MacroCmdIdx <= 0 ) || ( MacroCmdIdx > N_MAX_MAC_CMD ) )
    return (RT_INVMACC);

  stat = FileRead( &file, (int)MacroCmdIdx, 1, &macro, sizeof(t_macro_cmd) );
  if ( stat != R_NORMAL )
    return (RT_INVMACC);

  if ( !_tcscmp( macro.name, _T("") ) )
    return (RT_FAILED);

  *NumLegalObject = macro.n_legal_obj;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMacroLegalObjectIdx
**
** Description:		Get Idx of Legal Object using Macro Command Idx
**
** Input:			MacroCmdIdx		- Macro Command Idx
**					NumLegalObject	- Legal Object Index
** Output:			LegalObjectIdx	- Idx of Legal Object
**
** Return:			RETSTAT			- RT_NORMAL	If Macro Command exist
**									- RT_INVMACC	If invalid Macro Command Idx
**									- RT_INVOBJT	If invalid Object Index
**									- RT_FAILED	If Macro Command not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetMacroLegalObjectIdx	( GENIDX MacroCmdIdx, int NumLegalObject,
					GENIDX *LegalObjectIdx )
{
  RETCOND	stat;
  t_macro_cmd	macro;
//  int		i;
  FILEIDX	file;

  file.num = F_MACR;

  *LegalObjectIdx = (GENIDX)0;

  if ( ( MacroCmdIdx <= 0 ) || ( MacroCmdIdx > N_MAX_MAC_CMD ) )
    return (RT_INVMACC);

  if ( ( NumLegalObject <= 0 ) || ( NumLegalObject > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)MacroCmdIdx, 1, &macro, sizeof(t_macro_cmd) );
  if ( stat != R_NORMAL )
    return (RT_INVMACC);

  if ( !_tcscmp( macro.name, _T("") ) )
    return (RT_FAILED);

  *LegalObjectIdx = (GENIDX)macro.legal_obj[NumLegalObject-1];
  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMicroCmdName
**
** Description:		Get Micro Command Name using Micro Command Idx
**
** Input:			MicroCdmIdx		- Micro Cmd Idx
** Output:			MicroCmdName	- Micro Cmd Name
**
** Return:			RETSTAT			- RT_NORMAL	If Micro Command exist
**									- RT_INVMICR	If Micro Command Idx
**									- RT_FAILED	If Micro Command not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetMicroCmdName		( GENIDX MicroCmdIdx, MIC_CMDNAME MicroCmdName )
{
  RETCOND	stat;
  t_micro_cmd	micro;
//  int		i;
  FILEIDX	file;

  file.num = F_MICR;

  MicroCmdName[0] = '\0';

  if ( ( MicroCmdIdx <= 0 ) || ( MicroCmdIdx > N_MAX_MIC_CMD ) )
    return (RT_INVMICR);

  stat = FileRead( &file, (int)MicroCmdIdx, 1, &micro, sizeof(t_micro_cmd) );
  if ( stat != R_NORMAL )
    return (RT_INVMICR);

  if ( !_tcscmp( micro.name, _T("") ) )
    return (RT_FAILED);

//  StringFill ( micro.name, (L_MIC_CMD + 1) );
  _tcsncpy_s(MicroCmdName,sizeof(MicroCmdName), micro.name, L_MIC_CMD );
  MicroCmdName[L_MIC_CMD] = '\0';

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMicroCmdIdx
**
** Description:		Get Micro Command Idx using Micro Command Name
**
** Input:			MicroCmdName	- Micro Command Name
** Output:			MicroCmdIdx		- Micro Command Idx
**
** Return:			RETSTAT			- RT_NORMAL	If Micro Command exist
**									- RT_INVMICR	If invalid Micro Command Name
**									- RT_FAILED	If Micro Command not exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetMicroCmdIdx		( MIC_CMDNAME MicroCmdName, GENIDX *MicroCmdIdx )
{
  RETCOND	stat;
  t_micro_cmd	micro;
  int		i;
  FILEIDX	file;

  file.num = F_MICR;

  *MicroCmdIdx = (GENIDX)0;

  if ( !_tcscmp( MicroCmdName, _T("") ) )
    return (RT_INVMICR);

//  StringFill ( MicroCmdName, (L_MIC_CMD + 1) );

  for ( i = 0; i < N_MAX_MIC_CMD; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &micro, sizeof(t_micro_cmd) );

//    StringFill ( micro.name, (L_MIC_CMD + 1) );
    if ( !_tcsncmp ( MicroCmdName, micro.name, L_MIC_CMD ) )
     {
      *MicroCmdIdx = (GENIDX)(i+1);
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetSeqIdx
**
** Description:		Get Sequence Idx using Code, Object Type Idx, Zone Idx
**
** Input:			Code		- Sequence Code
**					ObjtIdx		- Object Type Idx
**					ZoneIdx		- Zone Idx
**
** Output:			SeqIdx		- Sequence Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Sequence exist
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_INVCODE	If invalid Micro Code
**								- RT_INVMICR	If Sequence NOT exist
** Modificata per utilizzo su NT.
*/

RETSTAT GetSeqIdx(int Code, int genObjt, GENIDX mastType, GENIDX ZoneIdx, int cellType, GENIDX *SeqIdx ){
	RETCOND		stat;
	RETSTAT		retSt;
	t_ope_seq	seq;
	int			i;
	GENIDX		superZoneIdx;
	FILEIDX		file;

	file.num = F_OSEQ;
	
	*SeqIdx = (GENIDX)0;

	if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
		return (RT_INVZONE);

	if ( ( genObjt < 0 ) || ( genObjt > N_MAX_OBJT ) )
		return (RT_INVOBJT);

	if ( ( Code != MICRO_INSERT ) && ( Code != MICRO_REMOVE ) )
		return (RT_INVCODE);
	
	retSt = GetZoneIdx(ZONE_FA, &superZoneIdx);
	if(retSt == RT_FAILED)
		return(retSt);
	retSt = CheckSuperZone(ZoneIdx, superZoneIdx);
	if(retSt == RT_FAILED)
		return(retSt);
	else if(retSt == RT_NORMAL)
		ZoneIdx = superZoneIdx;
	else{
		retSt = GetZoneIdx(ZONE_HECA, &superZoneIdx);
		if(retSt == RT_FAILED)
			return(retSt);
		retSt = CheckSuperZone(ZoneIdx, superZoneIdx);
		if(retSt == RT_FAILED)
			return(retSt);
		else if(retSt == RT_NORMAL)
			ZoneIdx = superZoneIdx;
	}


	for ( i = 0; i < N_MAX_OPE_SEQ; i++){
		stat = FileRead( &file, (i+1), 1, &seq, sizeof(t_ope_seq) );
		if ( ( seq.mic_com  == 0 ) && ( seq.nam_obj  == (GENIDX)0 ) && ( seq.nam_zone == (GENIDX)0 ) )
			continue;
		if ( ( seq.mic_com  == Code ) && ( seq.nam_obj  == genObjt ) && ( seq.nam_zone == ZoneIdx ) && (seq.cellType == cellType) && ( seq.mast == mastType)){
			*SeqIdx = (GENIDX)(i+1);
			return (RT_NORMAL);
		}
	}
	return (RT_INVMICR);
}

/*------------------------------------------------------------------------------
** Function:		GetSeqCode
**
** Description:		Get Sequence Code using Sequence Idx
**
** Input:			SeqIdx		- Sequence Idx
** Output:			Code		- Sequence Code
**
** Return:			RETSTAT		- RT_NORMAL	If Sequence exist
**								- RT_INVMICR	If invalid Sequence Idx
** Modificata per utilizzo su NT.
*/

RETSTAT GetSeqCode		( GENIDX SeqIdx, int *Code )
{
  RETCOND	stat;
  t_ope_seq	seq;
//  int		i;
  FILEIDX	file;

  file.num = F_OSEQ;

  *Code = -1;

  if ( ( SeqIdx <= 0 ) || ( SeqIdx > N_MAX_OPE_SEQ ) )
    return (RT_INVSEQ);

  stat = FileRead( &file, (int)SeqIdx, 1, &seq, sizeof(t_ope_seq) );
  if ( stat != R_NORMAL )
    return (RT_INVSEQ);

  *Code = seq.mic_com;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetSeqObjectIdx
**
** Description:		Get Sequence Object Idx using Sequence Idx
**
** Input:			SeqIdx		- Sequence Idx
** Output:			ObjectIdx	- Object Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Sequence exist
**								- RT_INVMICR	If invalid Sequence Idx
** Modificata per utilizzo su NT.
*/

RETSTAT GetSeqObjectIdx		( GENIDX SeqIdx, GENIDX *ObjectIdx )
{
  RETCOND	stat;
  t_ope_seq	seq;
//  int		i;
  FILEIDX	file;

  file.num = F_OSEQ;

  *ObjectIdx = (GENIDX)0;

  if ( ( SeqIdx <= 0 ) || ( SeqIdx > N_MAX_OPE_SEQ ) )
    return (RT_INVSEQ);

  stat = FileRead( &file, (int)SeqIdx, 1, &seq, sizeof(t_ope_seq) );
  if ( stat != R_NORMAL )
    return (RT_INVSEQ);

  *ObjectIdx = seq.nam_obj;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetSeqZoneIdx
**
** Description:		Get Sequence Zone Idx using Sequence Idx
**
** Input:			SeqIdx		- Sequence Idx
** Output:			ZoneIdx		- Zone Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Sequence exist
**								- RT_INVMICR	If invalid Sequence Idx
** Modificata per utilizzo su NT.
*/

RETSTAT GetSeqZoneIdx		( GENIDX SeqIdx, GENIDX *ZoneIdx )
{
  RETCOND	stat;
  t_ope_seq	seq;
//  int		i;
  FILEIDX	file;

  file.num = F_OSEQ;

  *ZoneIdx = (GENIDX)0;

  if ( ( SeqIdx <= 0 ) || ( SeqIdx > N_MAX_OPE_SEQ ) )
    return (RT_INVSEQ);

  stat = FileRead( &file, (int)SeqIdx, 1, &seq, sizeof(t_ope_seq) );
  if ( stat != R_NORMAL )
    return (RT_INVSEQ);

  *ZoneIdx = seq.nam_zone;

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseMacroName
**
** Description:		Get Macro Cmd Name using Phase Number ***
**
** Input:			Phase_num		- Phase Number
**
** Output:			MacroCmdName	- Macro Command Name
**
** Return:			RETSTAT			- RT_NORMAL	If Ok
**									- RT_INVPHAS	If invalid Phase Number
**									- RT_FAILED	If Macro Cmd non config.in Phase
** Modificata per utilizzo su NT.
*/

RETSTAT GetPhaseMacroName	( int Phase_Num, MAC_CMDNAME MacroCmdName )
{
  RETCOND	stat;
  phas_struc    phase;
  int		i;
  FILEIDX	file;

  file.num = F_PHAS;

  MacroCmdName[0] = '\0';

  if ( ( Phase_Num <= 0 ) || ( Phase_Num > N_MAX_PHASE ) )
    return (RT_INVPHAS);

  for ( i = 0; i < N_MAX_PHASE; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &phase , sizeof(phas_struc));
    if ( stat != R_NORMAL )
      return (RT_INVPHAS);

    if ( phase.phase  == Phase_Num )
     {
      if ( !_tcscmp( phase.cmd_type, _T("") ) )
      return (RT_FAILED);

//      StringFill ( phase.cmd_type, (L_MAC_CMD + 1) );
      _tcsncpy_s(MacroCmdName,sizeof(MacroCmdName), phase.cmd_type, L_MAC_CMD );
      MacroCmdName[L_MAC_CMD] = '\0';

      return (RT_NORMAL);
     }
   }

  return (RT_INVPHAS);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseObjtName
**
** Description:		Get Object Type Name using Phase Number
**
** Input:			Phase_num	- Phase Number
**
** Output:			ObjtName	- Object Type Name
**
** Return:			RETSTAT		- RT_NORMAL	If Ok
**								- RT_INVPHAS	If invalid Phase Number
**								- RT_FAILED	If Obj. Type not config.in Phase
*/

RETSTAT GetPhaseObjtName	( int Phase_Num, OBJTNAME ObjtName )
{
  RETCOND	stat;
  phas_struc    phase;
  int		i;
  FILEIDX	file;

  file.num = F_PHAS;

  ObjtName[0] = '\0';

  if ( ( Phase_Num <= 0 ) || ( Phase_Num > N_MAX_PHASE ) )
    return (RT_INVPHAS);

  for ( i = 0; i < N_MAX_PHASE; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &phase, sizeof(phas_struc) );
    if ( stat != R_NORMAL )
      return (RT_INVPHAS);

    if (  phase.phase  == Phase_Num )
     {
      if ( !_tcscmp( phase.obj_type, _T("") ) )
      return (RT_FAILED);

      if ( !_tcscmp( phase.obj_type, _T("        ") ) )
      return (RT_FAILED);

//      StringFill ( phase.obj_type, (L_OBJT_NAM + 1) );
      _tcsncpy_s(ObjtName,sizeof(ObjtName), phase.obj_type, L_OBJT_NAM );
      ObjtName[L_OBJT_NAM] = '\0';

      return (RT_NORMAL);
     }
   }

  return (RT_INVPHAS);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseSourceVirtCoo
**
** Description:		Get Source Virt. Coord. using Phase Number
**
** Input:			Phase_num	- Phase Number
**
** Output:			Virt_X		- Virtual Coordinate X
**					Virt_Y		- Virtual Coordinate Y
**
** Return:			RETSTAT		- RT_NORMAL	If Ok
**								- RT_INVPHAS	If invalid Phase Number
**								- RT_FAILED	If invalid Virt. Coo. in Phase
** Modificata per utilizzo su NT.
*/

RETSTAT GetPhaseSourceVirtCoo	( int Phase_Num, short int *Virt_X,
					short int *Virt_Y )
{
  RETCOND	stat;
//  RETSTAT	retstat;
  phas_struc    phase;
  int		i;
  FILEIDX	file;

  file.num = F_PHAS;

  *Virt_X = -1;
  *Virt_Y = -1;

  if ( ( Phase_Num <= 0 ) || ( Phase_Num > N_MAX_PHASE ) )
    return (RT_INVPHAS);

  for ( i = 0; i < N_MAX_PHASE; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &phase, sizeof(phas_struc) );
    if ( stat != R_NORMAL )
      return (RT_INVPHAS);

    if ( phase.phase == Phase_Num )
     {
      *Virt_X = phase.SV_X;
      *Virt_Y = phase.SV_Y;

      return (RT_NORMAL);
     }
   }

  return (RT_INVPHAS);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseDestVirtCoo
**
** Description:		Get Destination Virt. Coord. using Phase Number
**
** Input:			Phase_num	- Phase Number
**
** Output:			Virt_X		- Virtual Coordinate X
**					Virt_Y		- Virtual Coordinate Y
**
** Return:			RETSTAT		- RT_NORMAL	If Ok
**								- RT_INVPHAS	If invalid Phase Number
**								- RT_FAILED	If invalid Virt. Coo. in Phase
** Modificata per utilizzo su NT.
*/

RETSTAT GetPhaseDestVirtCoo	( int Phase_Num, short int *Virt_X,
					short int *Virt_Y )
{
  RETCOND	stat;
//  RETSTAT	retstat;
  phas_struc    phase;
  int		i;
  FILEIDX	file;

  file.num = F_PHAS;

  *Virt_X = -1;
  *Virt_Y = -1;

  if ( ( Phase_Num <= 0 ) || ( Phase_Num > N_MAX_PHASE ) )
    return (RT_INVPHAS);

  for ( i = 0; i < N_MAX_PHASE; i++ )
   {
    stat = FileRead( &file, (i+1), 1, &phase, sizeof(phas_struc));
    if ( stat != R_NORMAL )
      return (RT_INVPHAS);

    if ( phase.phase  == Phase_Num )
     {
      *Virt_X = phase.DV_X;
      *Virt_Y = phase.DV_Y;
/*
      if ( ( *Virt_X == 0 ) && ( *Virt_Y == 0 ) )
        return (RT_FAILED);
*/
      return (RT_NORMAL);
     }
   }

  return (RT_INVPHAS);
}



/*------------------------------------------------------------------------------
** Function:		GetPhaseObjectName
**
** Description:		Get Object Name using Phase Number
**
** Input:			Phase_num	- Phase Number
**
** Output:			ObjName		- Object Name
**
** Return:			RETSTAT		- RT_NORMAL	If Ok
**								- RT_INVPHAS	If invalid Phase Number
** Modificata per utilizzo su NT.
*/

RETSTAT GetPhaseObjectName	( int Phase_Num, OBJNAME ObjName )
{
  RETCOND	stat;
  phas_struc    phase;
  int		i;
  FILEIDX	file;

  file.num = F_PHAS;

  ObjName[0] = '\0';

  if ( ( Phase_Num <= 0 ) || ( Phase_Num > N_MAX_PHASE ) )
    return (RT_INVPHAS);

  for ( i = 0; i < N_MAX_PHASE; i++ )
   {
	  stat = FileRead( &file, (i+1), 1, &phase, sizeof(phas_struc) );
    if ( stat != R_NORMAL )
      return (RT_INVPHAS);

    if (phase.phase  == Phase_Num )
     {
      if ( !_tcscmp( phase.object, _T("") ) )
      return (RT_FAILED);

      if ( !_tcscmp( phase.object, _T("        ") ) )
      return (RT_FAILED);

//      StringFill ( phase.object, (L_OBJ_NAME + 1) );
      _tcsncpy_s(ObjName,sizeof(ObjName), phase.object, L_OBJ_NAME );
      ObjName[L_OBJ_NAME] = '\0';

      return (RT_NORMAL);
     }
   }

  return (RT_INVPHAS);
}

/*------------------------------------------------------------------------------
** Function:		CheckZoneConfZone
**
** Description:		Check if a Zone is confinant with another Zone
**
** Input:			ZoneIdx			- Zone Idx
**					ConfZoneIdx		- Confinant Zone Idx
** Output:
**
** Return:			RETSTAT			- RT_NORMAL	If Zone is conf. with Zone
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_FAILED	If Zone isn't confinant with
** Modificata per utilizzo su NT.
*/

RETSTAT CheckZoneConfZone	( GENIDX ZoneIdx, GENIDX ConfZoneIdx )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  int		j;
  FILEIDX	file;
  
  file.num = F_ZONE;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( ConfZoneIdx <= 0 ) || ( ConfZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  for ( j = 0; j < zone.n_conf_zone; j++ )
   {
    if ( j >= N_MAX_CONF )
      break;
    if ( zone.conf_zone[j].zone == ConfZoneIdx )
      return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckZoneFinalZone
**
** Description:		Check if a Zone is Final Zone for another Zone
**
** Input:			ZoneIdx			- Zone Idx
**					FinalZoneIdx	- Final Zone Idx
** Output:
**
** Return:			RETSTAT			- RT_NORMAL	If Zone is Final for Zone
**									- RT_INVZONE	If invalid Zone Idx
**									- RT_FAILED	If Zone isn't Final for Zone
** Modificata per utilizzo su NT.
*/

RETSTAT CheckZoneFinalZone	( GENIDX ZoneIdx, GENIDX FinalZoneIdx )
{
  RETCOND	stat;
  t_zone	zone;
  int		i;
  int		ind;
  FILEIDX	file;

  file.num = F_ZONE;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( FinalZoneIdx <= 0 ) || ( FinalZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  for ( i = 0; i < zone.n_legal_path; i++ )
   {
    if ( i >= N_MAX_PATH )
      break;
    ind = (zone.legal_path[i].n_zone - 1);
    if ( zone.legal_path[i].zone[ind] == FinalZoneIdx ) 
      return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckZoneAllowedObject
**
** Description:		Check if an Object is allowed for a Zone
**
** Input:			ZoneIdx		- Zone Idx
**					ObjtIdx		- Allowed Object Type Idx
** Output:
**
** Return:			RETSTAT		- RT_NORMAL	If Object is allowed for Zone
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If Object isn't allowed for Zone
** Modificata per utilizzo su NT.
*/

RETSTAT CheckZoneAllowedObject	( GENIDX ZoneIdx, GENIDX ObjtIdx )
{
  RETCOND	stat;
  t_zone	zone;
//  int		i;
  int		j;
  FILEIDX	file;

  file.num = F_ZONE;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_FAILED);

  for ( j = 0; j < zone.n_all_obj; j++ )
   {
    if ( j >= N_MAX_OBJT )
      break;
    if ( zone.all_obj[j].obj_t == ObjtIdx )
      return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckZonePhyCooForb
**
** Description:		Check if a couple of Physical Coord. is in Forbidden Area
**
** Input:			ZoneIdx		- Zone Idx
**					CooX		- Physical Coordinate X
**					CooY		- Physical Coordinate Y
** Output:
**
** Return:			RETSTAT		- RT_NORMAL	If Phys. Coord not in Forb. Area
**								- RT_INVZONE	If invalid Zone Idx
**								- RT_FAILED	If Phys. Coord in Forb. Area
** Modificata per utilizzo su NT.
*/

RETSTAT CheckZonePhyCooForb	( GENIDX ZoneIdx, float CooX, float CooY )
{
  RETCOND	stat;
  t_zone	zone;
  int		i;
//  int		j;
  FILEIDX	file;

  file.num = F_ZONE;

  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = FileRead( &file, (int)ZoneIdx, 1, &zone, sizeof(t_zone) );
  if ( stat != R_NORMAL )
    return (RT_INVZONE);

  if ( !_tcscmp( zone.name, _T("") ) )
    return (RT_INVZONE);

  for ( i = 0; i < zone.n_forb_area; i++ )
   {
    if ( i >= N_MAX_FORB )
      break;

    if ( ( CooX >= zone.forb_area[i].R_L_CooX ) &&
	 ( CooX <= zone.forb_area[i].L_H_CooX ) &&
	 ( CooY >= zone.forb_area[i].R_L_CooY ) &&
	 ( CooY <= zone.forb_area[i].L_H_CooY ) )
      return (RT_FAILED);
   }

  return (RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		CheckZoneVirtPLegalObjt
**
** Description:		Check if an Object is legal for a Zone in Virt. Param.
**
** Input:			Cell		- Cell Virtual Parameter
**					ObtIdx		- Object Type Idx
** Output:
**
** Return:			RETSTAT		- RT_NORMAL	If Object is legal
**								- RT_FAILED	If Object is NOT legal
*/

RETSTAT CheckZoneVirtPLegalObjt ( t_cell *Cell, GENIDX ObjtIdx ){
	RETSTAT		retSt;
	RETCOND		retCnd;
	int			i;
	GENIDX		zoneIdx;
	FILEIDX		fileZone;
	t_zone		zone;

	fileZone.num = F_ZONE;

	retSt = GetZoneIdxVirtCoo(Cell->Virt_X, Cell->Virt_Y, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	retCnd = FileRead(&fileZone, zoneIdx, 1, &zone, sizeof(zone));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	for(i = 0; i < N_MAX_OBJT; i++){
		if(zone.all_obj[i].obj_t == ObjtIdx ){
			return (RT_NORMAL);
			break;
		}
	}

	return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:			CheckZonePhyCooCorrid
**	
** Description:			Check if Physical Y is on Corridor
**
** Input:				CooY		- Y Physical Coordinate
**
** Output:
**
** Return:				RETSTAT		- RT_NORMAL	If CooY on Corridor
**									- RT_FAILED	If CooY NOT on Corridor
** Controllo solo la coordinata del punto di ingresso nel corridoio.
*/

RETSTAT	CheckZonePhyCooCorrid	( float CooY )
{
  RETSTAT	stat;
  int		i;
  int		zz;
  int		NumConfZone;
  int		n_p;
  float         *Corr_X, *Corr_Y;
  float		AppY;

  Corr_Y = NULL;
  Corr_X = NULL;
  
  for ( i = 0; i < N_MAX_ZONE; i++ )
   {
    stat = GetZoneNumConfZone ( (GENIDX)(i+1), &NumConfZone );
    if ( stat != RT_NORMAL )
      return (RT_FAILED);

    for ( zz = 1; zz <= NumConfZone; zz ++ )
     {
      stat = GetZoneCoordCorr ( (GENIDX)(i+1), NumConfZone,
					Corr_X, Corr_Y, &n_p );
      if ( stat != RT_NORMAL )
        return (RT_FAILED);

      if ( Corr_Y[0] <= 0.0 )
        continue;

      if ( Corr_Y[0] > CooY )
        AppY = Corr_Y[0] - CooY;
      else
        AppY = CooY - Corr_Y[0];

      if ( AppY <= TOLL_MM_CORR )
        return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckObjtLegalSource
**
** Description:		Check if a Source Zone is Legal for an Object Type
**
** Input:			ObjtIdx			- Object Type Idx
**					LegalSourceIdx	- Legal Source Zone Idx for this Object Type
** Output:
**
** Return:			RETSTAT			- RT_NORMAL	If Source Zone is Legal for Obj
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_INVSOUR	If invalid Source Zone Idx
**									- RT_FAILED	If Source Zone isn't Legal
** Modificata per utilizzo su NT.
*/

RETSTAT CheckObjtLegalSource(GENIDX ObjtIdx, GENIDX LegalSourceIdx){
	RETCOND			stat;
	RETSTAT			retSt;
	t_obj_type		objt;
	GENIDX			superZoneIdx;
	ZONENAME		zoneName;
	int				j;
	FILEIDX			file;

	file.num = F_OBJT;

	if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
		return (RT_INVOBJT);

	if ( ( LegalSourceIdx <= 0 ) || ( LegalSourceIdx > N_MAX_ZONE ) )
		return (RT_INVSOUR);

	retSt = GetZoneName(LegalSourceIdx, zoneName);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	retSt = GetSuperZoneFromName(zoneName, &superZoneIdx);
	if(retSt == RT_NORMAL)
		LegalSourceIdx = superZoneIdx;

	stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
	if ( stat != R_NORMAL )
		return (RT_INVOBJT);

	if ( !_tcscmp( objt.name, _T("") ) )
		return (RT_FAILED);

	for ( j = 0; j < objt.n_sour_zone; j++ ){
		if ( j >= N_MAX_ZONE )
			break;
		if ( objt.sour_zone[j] == LegalSourceIdx )
			return (RT_NORMAL);
	}

	return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckObjtLegalDest
**
** Description:		Check if a Destination Zone is Legal for an Object Type
**
** Input:			ObjtIdx			- Object Type Idx
**					LegalDestIdx	- Legal Dest. Zone Idx for this Object Type
** Output:
**
** Return:			RETSTAT			- RT_NORMAL	If Dest. Zone is Legal for Obj
**									- RT_INVOBJT	If invalid Object Type Idx
**									- RT_INVDEST	If invalid Dest. Zone Idx
**									- RT_FAILED	If Dest. Zone isn't Legal
** Modificata per utilizzo su NT.
*/

RETSTAT CheckObjtLegalDest	( GENIDX ObjtIdx, GENIDX LegalDestIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  int		j;
  FILEIDX	file;

  file.num = F_OBJT;
  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  if ( ( LegalDestIdx <= 0 ) || ( LegalDestIdx > N_MAX_ZONE ) )
    return (RT_INVDEST);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  for ( j = 0; j < objt.n_dest_zone; j++ )
   {
    if ( j >= N_MAX_ZONE )
      break;
    if ( objt.dest_zone[j] == LegalDestIdx )
      return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckObjtLegalObject
**
** Description:		Check if an Object is Legal Composed for an Object Type
**
** Input:			ObjtIdx				- Object Type Idx
**					LegalObjectIdx		- Legal Composed Object Idx for this Object Type
** Output:
**
** Return:			RETSTAT				- RT_NORMAL	If Comp. Object is Legal for Obj
**										- RT_INVOBJT	If invalid Object Type Idx
**										- RT_FAILED	If Comp. Object isn't Legal
** Modificata per utilizzo su NT.
*/

RETSTAT CheckObjtLegalObject	( GENIDX ObjtIdx, GENIDX LegalObjectIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
  int		j;
  FILEIDX	file;

  file.num = F_OBJT;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  if ( ( LegalObjectIdx <= 0 ) || ( LegalObjectIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  for ( j = 0; j < objt.n_legal_obj; j++ )
   {
    if ( j >= N_MAX_OBJT )
      break;
    if ( objt.legal_obj[j] == LegalObjectIdx )
      return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckObjtLegalContain
**
** Description:		Check if a Container is Legal for an Object Type
**
** Input:			ObjtIdx				- Object Type Idx
**					LegalContainIdx		- Legal Container Idx
** Output:
**
** Return:			RETSTAT				- RT_NORMAL	If Container is Legal for Object Type
**										- RT_INVOBJT	If invalid Object Type Idx
**										- RT_INVCONT	If invalid Container Idx
**										- RT_FAILED	If Container isn't Legal
** Modificata per utilizzo su NT.
*/

RETSTAT CheckObjtLegalContain	( GENIDX ObjtIdx, GENIDX LegalContainIdx )
{
  FILEIDX	file;

  file.num = F_OBJT;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

/**********************************************************************
  if ( ( LegalContainIdx <= 0 ) || ( LegalContainIdx > N_MAX_CONT ) )
    return (RT_INVCONT);
**********************************************************************/
/*
  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_FAILED);

  for ( j = 0; j < objt.n_cont_req; j++ )
   {
    if ( j >= N_MAX_CONT )
      break;
    if ( objt.cont_req[j] == LegalContainIdx )
      return (RT_NORMAL);
   }

  return (RT_FAILED);
  */
  if((ObjtIdx == 6) && (LegalContainIdx == Z1_CONT_HECA))
	  return(RT_NORMAL);
  else if(((ObjtIdx == 2) || (ObjtIdx == 3) || (ObjtIdx == 4)) && (LegalContainIdx == Z1_CONT_TK13))
	  return(RT_NORMAL);
  else
	  return(RT_FAILED);
}


/*------------------------------------------------------------------------------
** Function:		CheckObjtGenericType
**	
** Description:		Check if a Object Type is of a Generic Type
**
** Input:			GenObjt		- Generic Object Type Name
**					ObjtIdx		- Object Type Idx
** Output:
**
** Return:			RETSTAT		- RT_NORMAL	If Obj. Type is of Gener. Type
**								- RT_INVCONT	If invalid Container Idx
**								- RT_FAILED	If Obj. Type is NOT of Gener...
** Modificata per utilizzo su NT.
*/

RETSTAT CheckObjtGenericType	( OBJTNAME GenObjt, GENIDX ObjtIdx )
{
  RETCOND	stat;
  t_obj_type	objt;
//  int		i;
//  int		j;
  FILEIDX	file;

  file.num = F_OBJT;

  if ( ( ObjtIdx <= 0 ) || ( ObjtIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)ObjtIdx, 1, &objt, sizeof(t_obj_type) );
  if ( stat != R_NORMAL )
    return (RT_INVOBJT);

  if ( !_tcscmp( objt.name, _T("") ) )
    return (RT_INVOBJT);

//  StringFill ( GenObjt, (L_OBJT_NAM + 1) );
//  StringFill ( objt.obj_phase, (L_OBJT_NAM + 1) );

  if ( !_tcsncmp ( GenObjt, objt.obj_phase, L_OBJT_NAM ) )
      return (RT_NORMAL);

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckMacroLegalObject
**
** Description:		Check if an Object is Legal for a Macro Command
**
** Input:			MacroCmdIdx			- Macro Command Idx
**					LegalObjectIdx		- Legal Object Idx for this Macro Command
** Output:
**
** Return:			RETSTAT				- RT_NORMAL	If Object is Legal for Macro Cmd
**										- RT_INVMACC	If invalid Macro Cmd Idx
**										- RT_INVOBJT	If invalid Object Type Idx
**										- RT_FAILED	If Object isn't Legal
** Modificata per utilizzo su NT.
*/

RETSTAT CheckMacroLegalObject	( GENIDX MacroCmdIdx, GENIDX LegalObjectIdx )
{
  RETCOND	stat;
  t_macro_cmd	macro;
//  int		i;
  int		j;
  FILEIDX	file;

  file.num= F_MACR;

  if ( ( MacroCmdIdx <= 0 ) || ( MacroCmdIdx > N_MAX_MAC_CMD ) )
    return (RT_INVMACC);

  if ( ( LegalObjectIdx <= 0 ) || ( LegalObjectIdx > N_MAX_OBJT ) )
    return (RT_INVOBJT);

  stat = FileRead( &file, (int)MacroCmdIdx, 1, &macro, sizeof(t_macro_cmd) );
  if ( stat != R_NORMAL )
    return (RT_INVMACC);

  if ( !_tcscmp( macro.name, _T("") ) )
    return (RT_FAILED);

  for ( j = 0; j < macro.n_legal_obj; j++ )
   {
    if ( j >= N_MAX_OBJT )
      break;
    if ( macro.legal_obj[j] == LegalObjectIdx )
      return (RT_NORMAL);
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckZonePhyCooCorridZone
**
** Description:		Check if Physical Y is on Corridor in a Zone
**
** Input:			ZoneIdx		- Zone Idx
**					CooY		- Y Physical Coordinate
**
** Output:
**					CooX		- X Physical Coordinate
**
** Return:			RETSTAT		- RT_NORMAL	If CooY on Corridor
**								- RT_FAILED	If CooY NOT on Corridor
** Controllo solo la coordinata del punto di ingresso del corridoio.
*/

RETSTAT	CheckZonePhyCooCorridZone ( GENIDX ZoneIdx, float CooY, float *CooX )
{
  RETSTAT	stat;
  int		zz;
  int		NumConfZone;
  float		*Corr_X, *Corr_Y;
  float		AppY;
  int		n_p;
  
  Corr_X = NULL;
  Corr_Y = NULL;
  if ( ( ZoneIdx <= 0 ) || ( ZoneIdx > N_MAX_ZONE ) )
    return (RT_INVZONE);

  stat = GetZoneNumConfZone ( ZoneIdx, &NumConfZone );
  if ( stat != RT_NORMAL )
    return (RT_FAILED);

  for ( zz = 1; zz <= NumConfZone; zz ++ )
   {
    stat = GetZoneCoordCorr ( ZoneIdx, NumConfZone,
					Corr_X, Corr_Y, &n_p );
    if ( stat != RT_NORMAL )
      return (RT_FAILED);

    if ( Corr_Y[0] <= 0.0 )
      continue;

    if ( Corr_Y[0] > CooY )
      AppY = Corr_Y[0] - CooY;
    else
      AppY = CooY - Corr_Y[0];

    if ( AppY <= TOLL_MM_CORR )
     {
      *CooX = Corr_X[0];
      return (RT_NORMAL);
     }
   }

  return (RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetSuperZoneFromName
**
** Description:		Return the Idx of the super zone of a subZone
**
** Input:			subZone		- Zone name of the sub zone
** Output:			superZone	- Zone Idx of the super zone (if exists).
**
** Return:			RETSTAT		- RT_NORMAL	If the superZone Idx has been found correctly.
**								- RT_NOSUBZONE	If the subZone isn't a subZone
**								- RT_INVZONE If the subZone doesn't exists
** Inserita da M.Tavella 1/10/01
*/

RETSTAT GetSuperZoneFromName(ZONENAME subZone, GENIDX *superZone){
	RETSTAT	ret;
	GENIDX	zoneIdx;
	
	ret = GetZoneIdx(subZone, &zoneIdx);
	if(ret != RT_NORMAL)
		return(ret);
	ret = GetWideZoneIdx(zoneIdx, superZone);
	return(ret);
}

/*------------------------------------------------------------------------------
** Function:		CheckCellAllTVAngle
**
** Description:		Check if an angle is allowed in a cell.
**
** Input:			angle		- the angle to check
**					Virt_X		- X virtual coordinate of the cell to check
**					Virt_Y		- Y virtual coordinate of the cell to check
**
** Return:			RETSTAT		- RT_NORMAL	If the angle is allowed in the cell.
**								- RT_NOROTALL If the rotation isn't allowed
**								- RT_FAILED Other failures...
** Inserita da M.Tavella 1/10/01
*/

RETSTAT CheckCellAllTVAngle(int angle, int Virt_X, int Virt_Y){
	t_cell		*cell;
	int			i, recordNum, recordCount;
	GENIDX		zoneIdx;
	RETSTAT		retSt;
	RETCOND		retCnd;
	FILEIDX		file;
	FILEINFO	fileInfo;
	BOOL		Eof, found;

	retSt = GetZoneIdxVirtCoo(Virt_X, Virt_Y, &zoneIdx);
	if(retSt != RT_NORMAL)
		return (RT_FAILED);
	

	file.num = F_CE01 + zoneIdx - 1;

	retCnd = GetFileInfoEx(&file, &fileInfo);
	if(retCnd != R_NORMAL)
		return (RT_FAILED);

	recordNum = fileInfo.nrc;
	cell = new t_cell;

	Eof = false;
	found = false;
	recordCount = 0;

	while((!found) && (!Eof)){
		recordCount++;
		retCnd = FileRead(&file, recordCount, 1, cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((cell->Virt_X == Virt_X) && (cell->Virt_Y == Virt_Y))
			found = true;
		if(recordCount == recordNum)
			Eof = true;
	}

	
	if(!found)
		return(RT_FAILED);
	
	if(cell->Rot_Flag == 0){
		cell = NULL;
		delete cell;
		return (RT_NOROTALL);
	}
	
	for(i = 0; i < MAX_ROT_RANGE; i++){
		if((cell->Rot_Range.range_1[0] != -1) && (cell->Rot_Range.range_1[1] != -1) && (angle >= cell->Rot_Range.range_1[0]) && (angle <= cell->Rot_Range.range_1[1])){
			cell = NULL;
			delete cell;
			return(RT_NORMAL);
		}
		if((cell->Rot_Range.range_2[0] != -1) && (cell->Rot_Range.range_2[1] != -1) && (angle >= cell->Rot_Range.range_2[0]) && (angle <= cell->Rot_Range.range_2[1])){
			cell = NULL;
			delete cell;
			return(RT_NORMAL);
		}
		else if((cell->Rot_Range.range_1[1] == -1)  && (cell->Rot_Range.range_1[0] != -1) && (cell->Rot_Range.range_1[0] == angle)){
			cell = NULL;
			delete cell;
			return(RT_NORMAL);
		}
		else if((cell->Rot_Range.range_2[1] == -1) && (cell->Rot_Range.range_2[0] != -1)&& (cell->Rot_Range.range_2[0] == angle)){
			cell = NULL;
			delete cell;
			return(RT_NORMAL);
		}
		else{
			cell = NULL;
			delete cell;
			return(RT_FAILED);
		}
	}//End for//

	cell = NULL;
	delete cell;
	return (RT_FAILED);
}


/*------------------------------------------------------------------------------
** Function:		CheckAngleInRange
**
** Description:		Check if an angle is in a TV_angle struct.
**
** Input:			range		- the range to look into.
**					angle		- the angle to check 
**
** Return:			RETSTAT		- RT_NORMAL	If the angle is contained in the range.
**								- RT_NOROTALL If the angle isn't contained in the range.
**								- RT_FAILED Other failures...
** Inserita da M.Tavella 4/10/01
*/

RETSTAT CheckAngleInRange(TV_angle range, float angle){
	BOOL r1_is_angle, r2_is_angle, r2_is_empty; 

	//Controllo se l'intervallo contiene almeno un angolo valido.//
	if((range.range_1[0] == -1) && (range.range_1[1] == -1) && (range.range_2[0] == -1) && (range.range_2[1] == -1)){
		return(RT_FAILED);
	}
	//Controllo se il primo range � un solo angolo o un intervallo e controllo i valori degli angoli.
	if(range.range_1[1] == -1){
		r1_is_angle = true;
		if((range.range_1[0] < 0.0) && (range.range_1[0] > 315.0))
			return(RT_FAILED);
	}
	else{
		r1_is_angle = false;
		if((range.range_1[0] < 0.0) || (range.range_1[0] > 315.0))
			return(RT_FAILED);
		if((range.range_1[1] < 0.0) || (range.range_1[1] > 315.0))
			return(RT_FAILED);
		if(range.range_1[1] < range.range_1[0])
			return(RT_FAILED);
	}		

	if(range.range_2[0] == -1){
		r2_is_empty = true;
	}
	else if(range.range_2[1] == -1){
		r2_is_angle = true;
		r2_is_empty = false;
		if((range.range_2[0]<0) && (range.range_2[0] > 315))
			return(RT_FAILED);
	}
	else{
		r2_is_angle = false;
		r2_is_empty = false;
		if((range.range_2[0]< 0.0) || (range.range_2[0] > 315.0))
			return(RT_FAILED);
		if((range.range_2[1]< 0.0) || (range.range_2[1] > 315.0))
			return(RT_FAILED);
		if(range.range_2[1] < range.range_2[0])
			return(RT_FAILED);
	}

	if(angle < 0.0)
		angle = 0.0;
	else if(angle > 315.0)
		angle = 315.0;
	
	if(r1_is_angle && r2_is_empty){
		if((angle >= (float)(range.range_1[0] - TOLL_MM)) && (angle <= (float)(range.range_1[0] + TOLL_MM))){
			return (RT_NORMAL);
		}
		else
			return (RT_NOROTALL);
	}
	
	if(r1_is_angle && r2_is_angle){
		if((angle >= (float)(range.range_1[0] - TOLL_MM)) && (angle <= (float)(range.range_1[0] + TOLL_MM)))
			return (RT_NORMAL);
		else if((angle >= (float)(range.range_2[0] - TOLL_MM)) && (angle <= (float)(range.range_2[0] + TOLL_MM)))
			return (RT_NORMAL);
		else
			return (RT_NOROTALL);
	}

	if(!r1_is_angle && r2_is_empty){
		if((angle <= (float)(range.range_1[1] + TOLL_MM)) && (angle >= (float)(range.range_1[0] - TOLL_MM)))
			return (RT_NORMAL);
		else
			return (RT_NOROTALL);
	}
	
	if(!r1_is_angle && r2_is_angle && !r2_is_empty){
		if(((angle <= (float)(range.range_1[1] + TOLL_MM)) && (angle >= (float)(range.range_1[0] - TOLL_MM))) || ((angle <= (float)(range.range_2[0] + TOLL_MM)) && (angle >= (float)(range.range_2[0] - TOLL_MM))))
			return (RT_NORMAL);
		else
			return (RT_NOROTALL);
	}
	
	if(!r1_is_angle && !r2_is_angle && !r2_is_empty){
		if(((angle <= (float)(range.range_1[1] + TOLL_MM)) && (angle >= (float)(range.range_1[0] - TOLL_MM))) || 
		   ((angle <= (float)(range.range_2[1] + TOLL_MM)) && (angle >= (float)(range.range_2[0] - TOLL_MM))))
			return (RT_NORMAL);
		else
			return (RT_NOROTALL);
	}
	
	return (RT_FAILED);
}


/*------------------------------------------------------------------------------
** Function:		GetCellVirtCoo
**
** Description:		Retrieve a t_cell structure from the virtual coordinates.
**
** Input:			Virt_X		- X virtual coordinate of the cell to check
**					Virt_Y		- Y virtual coordinate of the cell to check
** Output:			cell		- Pointer to the cell
**
** Return:			RETSTAT		- RT_NORMAL	If the cell has benn successfully retrieved
**								- RT_FAILED If the cell hasn't been retrieved
** Inserita da M.Tavella 5/10/01
*/

RETSTAT GetCellVirtCoo(int Virt_X, int Virt_Y, t_cell *cell){
	int			recordNum, recordCount;
	GENIDX		zoneIdx;
	RETSTAT		retSt;
	RETCOND		retCnd;
	FILEIDX		file;
	FILEINFO	fileInfo;
	BOOL		Eof, found;

	retSt = GetZoneIdxVirtCoo(Virt_X, Virt_Y, &zoneIdx);
	if(retSt != RT_NORMAL)
		return (RT_FAILED);
	

	file.num = F_CE01 + zoneIdx - 1;

	retCnd = GetFileInfoEx(&file, &fileInfo);
	if(retCnd != R_NORMAL)
		return (RT_FAILED);

	recordNum = fileInfo.nrc;
	
	Eof = false;
	found = false;
	recordCount = 0;

	while((!found) && (!Eof)){
		recordCount++;
		retCnd = FileRead(&file, recordCount, 1, cell, sizeof(t_cell));
		if(retCnd != R_NORMAL){
			cell = NULL;
			return(RT_FAILED);
		}
		if((cell->Virt_X == Virt_X) && (cell->Virt_Y == Virt_Y))
			found = true;
		if(recordCount == recordNum)
			Eof = true;
	}

	if(!found){
		cell = NULL;
		return(RT_FAILED);
	}
	else
		return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetFirstAngle
**
** Description:		Retrieve the first legal angle in a range.
**
** Input:			TV_range	- X virtual coordinate of the cell to check
** Output:			angle		- the first angle in the range.
**
** Return:			RETSTAT		- RT_NORMAL	If an angle has been retrieved.
**								- RT_FAILED If there's no angle in the range
** Inserita da M.Tavella 5/10/01
*/

RETSTAT GetFirstAngle(TV_angle TV_range, float *angle){
float		i;
BOOL		found;

found = false;
i = 0;
while((!found) && (i <= 315)){
	if((i == TV_range.range_1[0]) && (TV_range.range_1[1] == -1 && (TV_range.range_1[0] != -1))){
		found = true;
		*angle = i;
		return RT_NORMAL;
	}
	else if((TV_range.range_1[0] != -1) && (TV_range.range_1[1] != -1) && ((i >= TV_range.range_1[0]) && (i <= TV_range.range_1[1]))){
		found = true;
		*angle = i;
		return RT_NORMAL;
	}
	else if ((i == TV_range.range_2[0]) && (TV_range.range_2[1] == -1 && (TV_range.range_2[0] != -1))){
		found = true;
		*angle = i;
		return RT_NORMAL;
	}
	else if((TV_range.range_2[0] != -1) && (TV_range.range_2[1] != -1) && ((i >= TV_range.range_2[0]) && (i <= TV_range.range_2[1]))){
		found = true;
		*angle = i;
		return RT_NORMAL;
	}
	i += 45.0;
}

return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckRot
**
** Description:		Check if the rotation from the angle ang_S to the angle ang_D
**					is possible in the cell (VirtX, VirtY).
**
** Input:			VirtX		- X virtual coordinate of the cell to check
**					VirtY		- Y virtual coordinate of the cell to check
**					ang_S		- Start rotation angle.
**					ang_D		- Stop rotation angle				
** Output:			rot			- Rotation is possible on 1 or 2 range.
**
** Return:			RETSTAT		- RT_NORMAL	If an angle has been retrieved.
**								- RT_FAILED If there's no angle in the range
** Inserita da M.Tavella 25/10/01
*/

RETSTAT CheckRot(int VirtX, int VirtY, float ang_S, float ang_D, int *rot){
	FILEIDX		cellFile;
	RETCOND		ret;
	RETSTAT		retSt;
	GENIDX		zoneIdx;
	int			i, cellNum;
	t_cell		*cell;
	
	*rot = 0;
	cell = new t_cell;
	GetZoneIdxVirtCoo(VirtX, VirtY, &zoneIdx);
	cellFile.num = F_CE01 + zoneIdx - 1;
	retSt = GetZoneCellNum(zoneIdx, &cellNum);
	if (retSt != RT_NORMAL)
		return(RT_FAILED);
	for(i = 1; i<=cellNum; i++){
		ret = FileRead(&cellFile, i, 1, cell, sizeof(t_cell));
		if (ret != R_NORMAL)
			return(RT_FAILED);
		if((cell->Virt_X == VirtX) && (cell->Virt_Y == VirtY)){
			if((cell->Rot_Flag == ROT_ALLOWED) && 
			   ((ang_S >= cell->Rot_Range.range_1[0]) &&
			    (ang_S <= cell->Rot_Range.range_1[1]) &&
				(ang_D >= cell->Rot_Range.range_1[0]) &&
			    (ang_D <= cell->Rot_Range.range_1[1]) &&
				(cell->Rot_Range.range_1[0] != -1) && (cell->Rot_Range.range_1[1] != -1))){
				*rot = 1;
				cell = NULL;
				delete cell;
				return (RT_NORMAL);
			}
			if((cell->Rot_Flag == ROT_ALLOWED) && 
			   ((ang_S >= cell->Rot_Range.range_2[0]) &&
			    (ang_S <= cell->Rot_Range.range_2[1]) &&
				(ang_D >= cell->Rot_Range.range_2[0]) &&
			    (ang_D <= cell->Rot_Range.range_2[1]) &&
				(cell->Rot_Range.range_2[0] != -1) && (cell->Rot_Range.range_2[1] != -1))){
				*rot = 2;
				cell = NULL;
				delete cell;
				return (RT_NORMAL);
			}
		}
	}
	delete cell;
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneCellNum
**
** Description:		Retrieve the number of cells in a zone.
** Input:			zoneIdx		- GENIDX of the zone to check.
** Output:			cellNum		- Number of the cell.
** Return:			RETSTAT		- RT_NORMAL	If an angle has been retrieved.
**								- RT_FAILED If there's no angle in the range
** Inserita da M.Tavella 25/10/01
*/

RETSTAT GetZoneCellNum(GENIDX zoneIdx, int *cellNum){
	FILEIDX		cellFile;
	RETCOND		ret;
	int			i;
	t_cell		cell;
	int			numCell;

	numCell = 0;
	cellFile.num = F_CE01 + zoneIdx - 1;
	
	for(i = 1; i <= N_MAX_CELL; i++){
		ret = FileRead(&cellFile, i, 1, &cell, sizeof(t_cell));
		if(ret != RT_NORMAL)
			return RT_FAILED;
		
		if(cell.Virt_X != 0)
			numCell++;

		if((cell.Virt_X == 0) && (cell.Virt_Y ==0))
			break;
	}
	*cellNum = numCell;
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetCellRotRange
**
** Description:		Retrieve a cell allowed rotation range.
** Input:			VirtX		- Cell virtual X coordinate
**					VirtY		- Cell virtual Y coordinate
** Output:			range		- Rotation range of the cell.
**					rotFlag		- Rotation flag.
** Return:			RETSTAT		- RT_NORMAL	If an angle has been retrieved.
**								- RT_FAILED If the cell doesn't exit.
** Inserita da M.Tavella 25/10/01
*/

RETSTAT GetCellRotRange(int VirtX, int VirtY, TV_angle *range, int *rotFlag){
	RETSTAT		ret;
	RETCOND		retCnd;
	int			i, cellNum;
	t_cell		*cell;
	FILEIDX		cellFile;
	GENIDX		zoneIdx;

	ret = GetZoneIdxVirtCoo(VirtX, VirtY, &zoneIdx);
	if(ret != RT_NORMAL)
		return (ret);

	cellFile.num = F_CE01 + zoneIdx - 1;
	
	ret = GetZoneCellNum(zoneIdx, &cellNum);
	if(ret != RT_NORMAL)
		return (ret);

	cell = new t_cell;
	for(i = 1; i <= cellNum; i++){
		retCnd = FileRead(&cellFile, i, 1, cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((cell->Virt_X == VirtX) && (cell->Virt_Y == VirtY)){
			*range = cell->Rot_Range;
			*rotFlag = cell->Rot_Flag;
			cell = NULL;
			delete cell;
			return RT_NORMAL;
		}
	}

	cell = NULL;
	delete cell;
	return RT_FAILED;
}

/*------------------------------------------------------------------------------
** Function:		IsMarkingAngle
**
** Description:		Check if an angle is good for marking operation 
**
** Input:			angle		- Angle to be checked
**
** Return:			RETSTAT		- RT_NORMAL	If the angle is good for marking
**								- RT_FAILED otherwise
*/
RETSTAT IsMarkingAngle(float angle){
	if(((angle >= (float)(45.0 - TOLL_MM)) && (angle <= (float)(45.0 + TOLL_MM)))	||
       ((angle >= (float)(135.0 - TOLL_MM)) && (angle <= (float)(135.0 + TOLL_MM)))	||
	   ((angle >= (float)(225.0 - TOLL_MM)) && (angle <= (float)(225.0 + TOLL_MM)))	||
	   ((angle >= (float)(315.0 - TOLL_MM)) && (angle <= (float)(315.0 + TOLL_MM))))
		return(RT_NORMAL);
	else
		return(RT_FAILED);

}

/*------------------------------------------------------------------------------
** Function:		GetBestAngle
**
** Description:		Retrieve the best dest legal angle in a range having source angle. 
**
** Input:			TV_range	- Dest. angle range
**					angle_S		- the source angle.
**					markFlag	- Marking is requested at destination
** Output:			angle_D		- the best dest angle in the range.
**
** Return:			RETSTAT		- RT_NORMAL	If an angle has been retrieved.
**								- RT_FAILED If there's no angle in the range
** Inserita da M.Tavella 30/10/01
*/
RETSTAT GetBestAngle(TV_angle TV_range,	float angle_S, int markFlag, float *angle_D){
	RETSTAT		retSt;
	float		tempAng;
	float		DiffAng;
	float		tempDiff;
	BOOL		found;

	found = false;
	tempAng = (float) 0.0;
	DiffAng = (float)999999.9;
	tempDiff = (float) 0.0;
	
	if(markFlag == 0){
		//Controllo se in dest esiste l'angolo di source. Se si il miglior angolo � quello
		//perch� mi permette di non eseguire rotazioni.//
		retSt = CheckAngleInRange(TV_range, angle_S);
		if(retSt == RT_NORMAL){
			found = true;
			*angle_D = angle_S;
			return(RT_NORMAL);
		}
		
		//Altrimenti cerco l'angolo interno al range di Dest con distanza minima dall'angolo
		//di source.//
		retSt = GetFirstAngle(TV_range, &tempAng);
		if(retSt != RT_NORMAL)
			return RT_FAILED;

		while(tempAng <= 315){
			retSt = CheckAngleInRange(TV_range, tempAng);
			if(retSt == RT_NORMAL){
				tempDiff = tempAng - angle_S;
				if(tempDiff < 0) 
					tempDiff = tempDiff * (-1);
				if(tempDiff < DiffAng){
					found = true;
					DiffAng = tempDiff;
					*angle_D = tempAng;
				}
			}
			tempAng += 45.0;
		}
	}
	else{
		//Marking -> priorit� agli angoli 45,135,225,315//
		//Controllo se in dest esiste l'angolo di source. Se si il miglior angolo � quello
		//perch� mi permette di non eseguire rotazioni.//
		
		retSt = CheckAngleInRange(TV_range, angle_S);
		if(retSt == RT_NORMAL){
			if(IsMarkingAngle(angle_S) == RT_NORMAL){
				found = true;
				*angle_D = angle_S;
				return(RT_NORMAL);
			}
		}
		
		//Altrimenti cerco l'angolo interno al range di Dest con distanza minima dall'angolo
		//di source.//
		retSt = GetFirstAngle(TV_range, &tempAng);
		if(retSt != RT_NORMAL)
			return RT_FAILED;

		while(tempAng <= 315){
			if(IsMarkingAngle(tempAng) == RT_FAILED){
				tempAng += 45.0;
				continue;
			}
			retSt = CheckAngleInRange(TV_range, tempAng);
			if(retSt == RT_NORMAL){
				tempDiff = tempAng - angle_S;
				if(tempDiff < 0) 
					tempDiff = tempDiff * (-1);
				if(tempDiff < DiffAng){
					found = true;
					DiffAng = tempDiff;
					*angle_D = tempAng;
				}
			}
			tempAng += 45.0;
		}

		if(!found){
			retSt = GetFirstAngle(TV_range, &tempAng);
			if(retSt != RT_NORMAL)
				return RT_FAILED;

			while(tempAng <= 315){
				retSt = CheckAngleInRange(TV_range, tempAng);
				if(retSt == RT_NORMAL){
					tempDiff = tempAng - angle_S;
					if(tempDiff < 0) 
						tempDiff = tempDiff * (-1);
					if(tempDiff < DiffAng){
						found = true;
						DiffAng = tempDiff;
						*angle_D = tempAng;
					}
				}
				tempAng += 45.0;
			}
		}
	
	}

	if(!found)
		return(RT_FAILED);
	else
		return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		CheckUnloadCell
**
** Description:		Check if a cell is of _T("unload-type"). 
**
** Input:			virtX		- Virtual X coordinate of the cell to check.
**					virtY		- Virtual Y coordinate of the cell to check.
**
** Return:			RETSTAT		- RT_NORMAL	If the cell is _T("unload-type")
**								- RT_FAILED if the cell is normal.
** Inserita da M.Tavella 30/10/01
*/
RETSTAT CheckUnloadCell(int virtX, int virtY){
	RETSTAT		retSt;
	GENIDX		zoneIdx;
	GENIDX		zone224, zone223, zone226;

	retSt = GetZoneIdx(ZONE_FA_03, &zone223);
	if(retSt != RT_NORMAL)
		return (retSt);

	retSt = GetZoneIdx(ZONE_FA_04, &zone224);
	if(retSt != RT_NORMAL)
		return (retSt);

	retSt = GetZoneIdx(ZONE_FA_06, &zone226);
	if(retSt != RT_NORMAL)
		return (retSt);

	retSt = GetZoneIdxVirtCoo(virtX, virtY, &zoneIdx);
	if(retSt != RT_NORMAL)
		return (retSt);

	if((zoneIdx != zone223) && (zoneIdx != zone224) && (zoneIdx != zone226))
		return(RT_FAILED);

	if((zoneIdx == zone223) && (virtX == 22315) && (virtY == 22330))
		return(RT_NORMAL);

	if((zoneIdx == zone224) && (virtX == 22415) && ((virtY >= 22402) && (virtY <= 22422)))
		return(RT_NORMAL);

	if((zoneIdx == zone226) && ((virtX >= 22601) && (virtX <= 22613)) && ((virtY >= 22630) && (virtY <= 22632)))
		return(RT_NORMAL);

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		IsClusZone
**
** Description:		Check if a zone is for cluster storage.
**
** Input:			ZoneIdx			- Idx of the zone to check.
**
** Return:			RETSTAT			- RT_NORMAL	If zone is for cluster storage.
**									- RT_FAILED	otherwise
*/
RETSTAT IsClusZone(GENIDX zoneIdx){
	if(((zoneIdx >= 16) && (zoneIdx <= 17)) || (zoneIdx == 2) || (zoneIdx == 3))
		return(RT_NORMAL);
	else
		return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		IsFADSCell
**
** Description:		Check if a cell is for FA detection system.
**
** Input:			vx				- Virtual coordinate x of the cell to check.
**					vy				- Virtual coordinate y of the cell to check.
**
** Return:			RETSTAT			- RT_NORMAL	If cell is for FADS.
**									- RT_FAILED	otherwise
*/
RETSTAT IsFADSCell(int vx, int vy){
	if(((vx == 2401) && (vy == 2408)) || (vx == 24001) || (vy == 2402))
		return(RT_NORMAL);
	else
		return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		IsCovCell
**
** Description:		Check if a cell is a cover seat.
**
** Input:			vx				- Virtual coordinate x of the cell to check.
**					vy				- Virtual coordinate y of the cell to check.
**
** Return:			RETSTAT			- RT_NORMAL	If cell is for FADS.
**									- RT_FAILED	otherwise
*/
RETSTAT IsCovCell(int vx, int vy){
	if(((vx == 2401) && (vy == 2404)) || (vx == 2401) || (vy == 2406))
		return(RT_NORMAL);
	else
		return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		IsClusCasCell
**
** Description:		Check if a cell is the cluster casing home.
**
** Input:			vx				- Virtual coordinate x of the cell to check.
**					vy				- Virtual coordinate y of the cell to check.
**
** Return:			RETSTAT			- RT_NORMAL	If cell is for FADS.
**									- RT_FAILED	otherwise
*/
RETSTAT IsClusCasCell(int vx, int vy){
	RETSTAT		retSt;
	int			type;

	retSt = GetCellType((short int)(vx), (short int)(vy), &type);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	if(type != CELL_COVER_PLUG_EX)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtWeight
**
** Description:		Retrieve an object type weight.
**
** Input:			objtIdx			- Object type Idx to retrieve weight.
** Output:			weight			- weight of the object type.
**
** Return:			RETSTAT			- RT_NORMAL	If objtIdx is valid.
**									- RT_FAILED	otherwise
*/
RETSTAT GetObjtWeight(GENIDX objtIdx, float *weight){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileObjt;
	OBJTNAME	objtName;
	t_obj_type	objt;

	fileObjt.num = F_OBJT;
	*weight = 0.0;
	
	retSt = GetObjtName(objtIdx, objtName);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = FileRead(&fileObjt, objtIdx, 1, &objt, sizeof(objt));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	*weight = objt.obj_dim.z;
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetObjtWeight
**
** Description:		Set an object type weight.
**
** Input:			objtIdx			- Object type Idx to set weight.
** Output:			weight			- weight of the object type.
**
** Return:			RETSTAT			- RT_NORMAL	If objtIdx is valid.
**									- RT_FAILED	otherwise
*/
RETSTAT SetObjtWeight(GENIDX objtIdx, float weight){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileObjt;
	OBJTNAME	objtName;
	t_obj_type	objt;

	fileObjt.num = F_OBJT;
	if(weight < 0.0)
		return(RT_FAILED);
	
	retSt = GetObjtName(objtIdx, objtName);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = FileRead(&fileObjt, objtIdx, 1, &objt, sizeof(objt));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	objt.obj_dim.z = weight;
	
	retCnd = FileWrite(&fileObjt, objtIdx, 1, &objt, sizeof(objt));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}
/*------------------------------------------------------------------------------
** Function:		GetClusCasObjIdx
**
** Description:		Retrieve cluster casing object Idx.
**
** Output:			objIdx			- Object Idx to retrieve.
**
** Return:			RETSTAT			- RT_NORMAL	If objIdx has been found.
**									- RT_FAILED	otherwise
*/
RETSTAT GetClusCasObjIdx(GENIDX *objIdx){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileObje;
	t_obj		temp;
	int			i;
	GENIDX		clusCasIdx;

	fileObje.num = F_OBJE;

	retSt = GetObjtIdx(OBJT_CLUS_CAS, &clusCasIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = 0; i < 1000; i++){
		retCnd = FileRead(&fileObje, i + 1, 1, &temp, sizeof(temp));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(temp.obj_type == clusCasIdx){
			*objIdx = temp.idx;
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetDynMmxyPos
**
** Description:		Retrieve main mast dynamic x,y position.
**
** Output:			posX			- main mast dynamic x position
**					posY			- main mast dynamic y position
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been found.
**									- RT_FAILED	otherwise
*/
RETSTAT GetDynMmxyPos(float *posX, float *posY){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	dynamic_struc	dyn;
	

	fileDynp.num = F_DYNP;

	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	*posX = dyn.mm_x;
	*posY = dyn.mm_y;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetDynMastPos
**
** Description:		Retrieve a mast rod dynamic x,y position.
**
** Input			mast			- Mast to retrieve position
** Output:			posX			- Mast dynamic x position
**					posY			- Mast dynamic y position
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been found.
**									- RT_FAILED	otherwise
*/
RETSTAT GetDynMastPos(int mastType, float *posX, float *posY){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	float			falv_x;
	float			falv_y;
	dynamic_struc	dyn;
	

	fileDynp.num = F_DYNP;

	if((mastType < MAIN_MAST) && (mastType > DMP_MAST))
		return(RT_FAILED);

	GetFALVOffset(&falv_x, &falv_y);

	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	switch(mastType){
	case MAIN_MAST:
		*posX = dyn.mm_x;
		*posY = dyn.mm_y;
		break;
	case FALC_MAST:
	case DMP_MAST:
		*posX = dyn.mm_x + (float)(falv_x);
		*posY = dyn.mm_y + (float)(falv_y);
		break;
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetDynFCxyPos
**
** Description:		Retrieve Fuel Assembly control dynamic x,y position.
**
** Output:			posX			- FC dynamic x position
**					posY			- FC dynamic y position
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been found.
**									- RT_FAILED	otherwise
*/
RETSTAT GetDynFCxyPos(float *posX, float *posY){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	float			falv_x;
	float			falv_y;
	dynamic_struc	dyn;
	

	fileDynp.num = F_DYNP;

	GetFALVOffset(&falv_x, &falv_y);

	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	*posX = dyn.mm_x + falv_x;
	*posY = dyn.mm_y + falv_y;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDynFCxyPos
**
** Description:		Set Fuel Assembly control dynamic x,y position.
**
** Input:			posX			- FC dynamic x position
**					posY			- FC dynamic y position
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been found.
**									- RT_FAILED	otherwise
*/
RETSTAT SetDynFCxyPos(float posX, float posY){
	RETSTAT			retSt;
	FILEIDX			fileDynp;
	float			falv_x;
	float			falv_y;
	dynamic_struc	dyn;
	

	fileDynp.num = F_DYNP;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	GetFALVOffset(&falv_x, &falv_y);

	dyn.mm_x = posX - falv_x;
	dyn.mm_y = posY - falv_y;

	retSt = SetDynStruc(dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDynMmxPos
**
** Description:		Set main mast dynamic x position.
**
** Input:			posX			- main mast dynamic x position
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been set.
**									- RT_FAILED	otherwise
*/
RETSTAT SetDynMmxPos(float posX){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	dynamic_struc	dyn;
	

	fileDynp.num = F_DYNP;

	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	dyn.mm_x = posX;
	
	retCnd = FileWrite(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDynMmyPos
**
** Description:		Set main mast dynamic y position.
**
** Input:			posY			- main mast dynamic y position
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been set.
**									- RT_FAILED	otherwise
*/
RETSTAT SetDynMmyPos(float posY){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	dynamic_struc	dyn;
	

	fileDynp.num = F_DYNP;

	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	dyn.mm_y = posY;
	
	retCnd = FileWrite(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjWeight
**
** Description:		Set the weight of a object
**
** Input:			objIdx			- Object idx
** Output:			weight			- weight of the object
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been set.
**									- RT_FAILED	otherwise
*/

RETSTAT GetObjWeight(GENIDX objIdx, float *weight){
	RETCOND		retCnd;
	t_obj		obj;
	FILEIDX		fileObje;
	int			rec;

	fileObje.num = F_OBJE;

	for(rec = 1; rec < N_MAX_OBJ; rec++){
		retCnd = FileRead(&fileObje, rec, 1, &obj, sizeof(obj));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(obj.idx == objIdx)
			break;
	}
	
	*weight = obj.obj_pos.z;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetObjWeight
**
** Description:		Set the weight of a object
**
** Input:			objIdx			- Object idx
**					weight			- weight of the object
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been set.
**									- RT_FAILED	otherwise
*/

RETSTAT SetObjWeight(GENIDX objIdx, float weight){
	RETCOND		retCnd;
	t_obj		obj;
	FILEIDX		fileObje;
	int			rec;

	fileObje.num = F_OBJE;

	for(rec = 1; rec < N_MAX_OBJ; rec++){
		retCnd = FileRead(&fileObje, rec, 1, &obj, sizeof(obj));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(obj.idx == objIdx)
			break;
	}
	
	obj.obj_pos.z = weight;

	retCnd = FileWrite(&fileObje, rec, 1, &obj, sizeof(obj));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNameAllMatrixPosition
**
** Description:		Retrieve the allowed matrix position of a Zone
**
** Input:			zoneName		- Zone name
** Output:			position		- Posisition in matrix
**
** Return:			RETSTAT			- RT_NORMAL	If pos. has been set.
**									- RT_FAILED	otherwise
*/
RETSTAT GetZoneNameAllMatrixPosition(ZONENAME zoneName, int *position){
	if(!_tcscmp(zoneName, _T("Z1")))
		*position = ALL_MATRIX_Z1;
	else if(!_tcscmp(zoneName, _T("Z21")))
		*position = ALL_MATRIX_Z21;
	else if(!_tcscmp(zoneName, _T("Z22")))
		*position = ALL_MATRIX_Z22;
	else if(!_tcscmp(zoneName, _T("Z23")))
		*position = ALL_MATRIX_Z23;
	else if(!_tcscmp(zoneName, _T("Z3")))
		*position = ALL_MATRIX_Z3;
	else
		return RT_FAILED;
	return RT_NORMAL;
}

/*------------------------------------------------------------------------------
** Function:		GetZoneNameFromMatrixPosition
**
** Description:		Retrieve the zone name from the allowed matrix position
**
** Input:			position		- Posisition in matrix
** Output:			zoneName		- Zone Name
**
** Return:			RETSTAT			- RT_NORMAL	If zoneName has been found.
**									- RT_FAILED	otherwise
*/
RETSTAT GetZoneNameFromMatrixPosition(int position, ZONENAME zoneName){
	if(position == ALL_MATRIX_Z1)
		_tcscpy_s(zoneName,sizeof(zoneName), _T("Z1"));
	else if(position == ALL_MATRIX_Z21)
		_tcscpy_s(zoneName,sizeof(zoneName), _T("Z21"));
	else if(position == ALL_MATRIX_Z22)
		_tcscpy_s(zoneName,sizeof(zoneName), _T("Z22"));
	else if(position == ALL_MATRIX_Z23)
		_tcscpy_s(zoneName,sizeof(zoneName), _T("Z23"));
	else if(position == ALL_MATRIX_Z3)
		_tcscpy_s(zoneName,sizeof(zoneName), _T("Z3"));
	else 
		return(RT_FAILED);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycDescription
**
** Description:		Retrieve a tecnological cycle decsription
**
** Input:			id			- Tecnological cycle id
** Output:			descr		- Tecnological cycle description
**
** Return:			RETSTAT			- RT_NORMAL	If descr has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetTechCycDescription(TECCYCID id, TECCYCDESCR descr){
	RETCOND		retCnd;
	FILEIDX		fileTecc;
	int			i;
	t_teccyc	tc;
	bool		found;

	fileTecc.num = F_TECC;
	found = false;

	for(i = 1; i <= N_MAX_TECC; i++){
		retCnd = FileRead(&fileTecc, i, 1, &tc, sizeof(t_teccyc));
		if(retCnd !=R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(tc.id, id)){
			_tcscpy_s(descr,sizeof(descr), tc.descr);
			found = true;
		}
	}

	if(found)
		return(RT_NORMAL);
	else
		return(RT_FAILED);

}

/*------------------------------------------------------------------------------
** Function:		GetTechCycRecNum
**
** Description:		Retrieve a tecnological cycle record number (in F.TECC DAFS file).
**
** Input:			id			- Tecnological cycle id
** Output:			recNum		- Tecnological cycle record number
**
** Return:			RETSTAT			- RT_NORMAL	If record number has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetTechCycRecNum(TECCYCID id, int *recNum){
	RETCOND		retCnd;
	FILEIDX		fileTecc;
	int			i;
	t_teccyc	tc;
	bool		found;

	fileTecc.num = F_TECC;
	found = false;

	for(i = 1; i <= N_MAX_TECC; i++){
		retCnd = FileRead(&fileTecc, i, 1, &tc, sizeof(t_teccyc));
		if(retCnd !=R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(tc.id, id)){
			*recNum = i;
			found = true;
		}
	}

	if(found)
		return(RT_NORMAL);
	else
		return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCyc
**
** Description:		Retrieve a tecnological cycle structure (in F.TECC DAFS file).
**
** Input:			id			- Tecnological cycle id
** Output:			*tc			- Tecnological cycle structure
**
** Return:			RETSTAT			- RT_NORMAL	If record  has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetTechCyc(TECCYCID id, t_teccyc *tc){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileTecc;
	int			rec;

	fileTecc.num = F_TECC;
	

	retSt = GetTechCycRecNum(id, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	retCnd = FileRead(&fileTecc, rec, 1, tc, sizeof(t_teccyc));
	if(retCnd !=R_NORMAL)
		return(RT_FAILED);
		
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneSuperZone
**
** Description:		Retrieve the super-zone of a specified zone
**
** Input:			zoneName			- zone name
** Output:			superZoneName		- super zone name
**
** Return:			RETSTAT			- RT_NORMAL	If super zone  has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetZoneSuperZone(ZONENAME zoneName, ZONENAME superZoneName){
	if((!_tcscmp(zoneName, _T("Z1"))) || (!_tcscmp(zoneName, _T("Z2"))) || (!_tcscmp(zoneName, _T("Z3")))  || (!_tcscmp(zoneName, _T("Z23")))){
		_stprintf_s(superZoneName,sizeof(superZoneName), _T("%s"), zoneName);
		return(RT_NORMAL);
	}
	else if((!_tcscmp(zoneName, _T("Z211"))) || (!_tcscmp(zoneName, _T("Z212"))) || (!_tcscmp(zoneName, _T("Z213"))) || (!_tcscmp(zoneName, _T("Z214"))) || (!_tcscmp(zoneName, _T("Z215")))  || (!_tcscmp(zoneName, _T("Z216")))  || (!_tcscmp(zoneName, _T("Z217")))  || (!_tcscmp(zoneName, _T("Z218")))  || (!_tcscmp(zoneName, _T("Z219")))  || (!_tcscmp(zoneName, _T("Z210")))){
		_stprintf_s(superZoneName,sizeof(superZoneName), _T("%s"), _T("Z21"));
		return(RT_NORMAL);
	}
	else if((!_tcscmp(zoneName, _T("Z221"))) || (!_tcscmp(zoneName, _T("Z222")))){
		_stprintf_s(superZoneName,sizeof(superZoneName), _T("%s"), _T("Z22"));
		return(RT_NORMAL);
	}
	else
		return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycId
**
** Description:		Retrieve the technological cycle Id from its Idx
**
** Input:			idx			- technological cycle Idx
** Output:			id			- technological cycle Id
**
** Return:			RETSTAT			- RT_NORMAL	If Id  has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetTechCycId(GENIDX idx, TECCYCID id){
	RETCOND		retCnd;
	FILEIDX		fileTecc;
	t_teccyc	tc;
	int			rec;

	fileTecc.num = F_TECC;

	for(rec = 1; rec <= N_MAX_TECC; rec++){
		retCnd = FileRead(&fileTecc, rec, 1, &tc, sizeof(t_teccyc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(tc.idx == idx){
			_stprintf_s(id,sizeof(id), _T("%s"), tc.id);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycIdx
**
** Description:		Retrieve the technological cycle Idx from its Id
**
** Input:			id			- technological cycle Id
** Output:			idx			- technological cycle Idx
**
** Return:			RETSTAT			- RT_NORMAL	If Idx has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetTechCycIdx(TECCYCID id, GENIDX *idx){
	RETCOND		retCnd;
	FILEIDX		fileTecc;
	t_teccyc	tc;
	int			rec;

	fileTecc.num = F_TECC;

	for(rec = 1; rec <= N_MAX_TECC; rec++){
		retCnd = FileRead(&fileTecc, rec, 1, &tc, sizeof(t_teccyc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(tc.id, id)){
			*idx = tc.idx;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhasTecCycIdx
**
** Description:		Retrieve the tecnological cycle Idx of a phase
**
** Input:			currentPhas			- phase number
** Output:			tecCycIdx			- technological cycle Idx
**
** Return:			RETSTAT			- RT_NORMAL	If Idx  has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetPhasTecCycIdx(GENIDX currentPhas, GENIDX *tecCycIdx){
	RETCOND			retCnd;
	phas_struc		phas;
	FILEIDX			filePhas;
	int				i;

	filePhas.num = F_PHAS;
	
	for(i = 1; i < N_MAX_PHASE; i++){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return RT_FAILED;
		if(phas.phase == currentPhas){
			*tecCycIdx = phas.tecCycIdx;
			return(RT_NORMAL);
		}
	}

	return RT_FAILED;
}

RETSTAT GetPhasMarkReq(int phasNum, int *flag){
	RETCOND			retCnd;
	phas_struc		phas;
	FILEIDX			filePhas;
	int				i;

	filePhas.num = F_PHAS;
	
	for(i = 1; i < N_MAX_PHASE; i++){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return RT_FAILED;
		if(phas.phase == phasNum){
			*flag = phas.markReq;
			return(RT_NORMAL);
		}
	}

	return RT_FAILED;
}

RETSTAT SetPhasMarkReq(int phasNum, int flag){
	RETCOND			retCnd;
	phas_struc		phas;
	FILEIDX			filePhas;
	int				i;

	filePhas.num = F_PHAS;
	
	for(i = 1; i < N_MAX_PHASE; i++){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return RT_FAILED;
		if(phas.phase == phasNum){
			phas.markReq = flag;
			retCnd = FileWrite(&filePhas, i, 1, &phas, sizeof(phas));
			if(retCnd != R_NORMAL)
				return RT_FAILED;
			return(RT_NORMAL);
		}
	}

	return RT_FAILED;
}

/*------------------------------------------------------------------------------
** Function:		GetPlugSeatCaskIdx
**
** Description:		Retrieve the Idx of the cask from where the cover in the plug
**					has been taken.
**
** Input:			svx					- plug seat virtual x coordinate
**					svy					- plug seat virtual y coordinate
** Output:			objIdx				- Idx of the cask.
**
** Return:			RETSTAT			- RT_NORMAL	If Idx  has been found
**									- RT_FAILED	otherwise
*/
RETSTAT GetPlugSeatCaskIdx(short int svx, short int svy, GENIDX *objIdx){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	dynamic_struc	dyn;

	fileDynp.num = F_DYNP;

	if((svx != CP1_VX) || ((svy != CP1_VY) && (svy != CP2_VY)))
		return(RT_FAILED);
	
	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(svy == CP1_VY)
		*objIdx = dyn.coverPlug1Obj;
	else if (svy == CP2_VY)
		*objIdx = dyn.coverPlug2Obj;
	else
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetPlugSeatCaskIdx
**
** Description:		Set the Idx of the cask from where the cover in the plug
**					has been taken.
**
** Input:			svx					- plug seat virtual x coordinate
**					svy					- plug seat virtual y coordinate
**					objIdx				- Idx of the cask.
**
** Return:			RETSTAT			- RT_NORMAL	If Idx  has been set
**									- RT_FAILED	otherwise
*/
RETSTAT SetPlugSeatCaskIdx(short int svx, short int svy, GENIDX objIdx){
	RETCOND			retCnd;
	FILEIDX			fileDynp;
	dynamic_struc	dyn;

	fileDynp.num = F_DYNP;

	if((svx != CP1_VX	) || ((svy != CP1_VY) && (svy != CP2_VY)))
		return(RT_FAILED);
	
	retCnd = FileRead(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(svy == CP1_VY){
		/*
		if((dyn.coverPlug1Obj != 0) && (objIdx != 0))
			return(RT_FAILED);
		*/
		dyn.coverPlug1Obj = objIdx;
	}
	else if (svy == CP2_VY){
		/*
		if((dyn.coverPlug2Obj != 0) && (objIdx != 0))
			return(RT_FAILED);
		*/
		dyn.coverPlug2Obj = objIdx;
	}
	else
		return(RT_FAILED);
	
	retCnd = FileWrite(&fileDynp, 1, 1, &dyn, sizeof(dyn));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		FindCaskCoordinates
**
** Description:		Retrieve virtual coordinbates of the cell conytaining the cask
**					wich idx id objIdx
**
** Input:			objIdx				- Idx of the cask.
** Output:			svx					- cask virtual x coordinate
**					svy					- cask virtual y coordinate
**
** Return:			RETSTAT			- RT_NORMAL	If coordinates have been found
**									- RT_FAILED	otherwise
*/
RETSTAT FindCaskCoordinates(GENIDX objIdx, short int *svx, short int *svy){
	RETCOND			retCnd;
	RETSTAT			retSt;
	FILEIDX			fileCell;
	GENIDX			zoneIdx;
	GENIDX			objtIdx;
	t_cell			cell;
	int				hecaGenCode, i;

	retSt = GetObjtIdx(OBJT_HECA, &objtIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	retSt = GetObjtGenericTypeCode(objtIdx, &hecaGenCode);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	retSt = GetZoneIdx(_T("Z231"), &zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	fileCell.num = F_CE01 + zoneIdx - 1;

	for(i = 1; i < N_MAX_CELL; i++){
		retCnd = FileRead(&fileCell, i, 1, &cell, sizeof(cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(cell.objt_cell.o_id[hecaGenCode] == objIdx){
			*svx = cell.Virt_X;
			*svy = cell.Virt_Y;
			return(RT_NORMAL);
		}
	}
	
	retSt = GetZoneIdx(_T("Z232"), &zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	fileCell.num = F_CE01 + zoneIdx - 1;

	for(i = 1; i < N_MAX_CELL; i++){
		retCnd = FileRead(&fileCell, i, 1, &cell, sizeof(cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(cell.objt_cell.o_id[hecaGenCode] == objIdx){
			*svx = cell.Virt_X;
			*svy = cell.Virt_Y;
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}


/*------------------------------------------------------------------------------
** Function:		CheckPhaseFisibility
**
** Description:		Check if a phase will be fisible in future.
**
** Input:			svx					- phase source virtual x coordinate
**					svy					- phase source virtual y coordinate
**					dvx					- phase dest. virtual x coordinate
**					dvy					- phase dest. virtual y coordinate
**					objtIdx				- phase object type Idx
** Output:			objIdx				- Idx of the object that will be moved.
**
** Return:			RETSTAT			- RT_NORMAL	If coordinates have been found
**									- RT_FAILED	otherwise
*/
RETSTAT CheckPhaseFisibility(short int svx, short int svy, short int dvx, short int dvy, GENIDX objtIdx, GENIDX *objIdx){
	RETSTAT			retSt;
	RETCOND			retCnd;
	phas_struc		phas;
	phas_struc		phasCheck;
	FILEIDX			filePhas;
	GENIDX			phasObjtIdx;
	GENIDX			phasObjIdx;
	int				schedNum;
	int				i, j;
	bool			objInSourceFound;
	bool			objMoved;
	bool			objInDest;
	
	schedNum = 0;
	filePhas.num = F_PHAS;
	objInSourceFound = false;
	objMoved = false;
	objInDest = false;

	//Controllo che numero di esecuzione avrebbe la fase da controllare.//
	for(i = 1; i < N_MAX_PHASE; i++){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == 0){
			schedNum = i;
			break;
		}
	}
	
	//Se la cella di partenza � vuota, controllo se esiste una fase precedente a questa che mette
	//un'oggetto di tipo objtIdx nella cella (svx,svy).//
	for(i = schedNum - 1; i > 0; i--){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if((retCnd != R_NORMAL) || (phas.phase == 0))
			return(RT_FAILED);
		//Controllo se la fase corrisponde a un ciclo tecnologico (MOVE)//
		if(phas.tecCycIdx != 0){
			if((phas.DV_X == svx) && (phas.DV_Y == svy)){
				retSt = GetObjtIdx(phas.obj_type, &phasObjtIdx);
				if(retSt != RT_NORMAL)
					return(retSt);
				if(phasObjtIdx == objtIdx){
					//Controllo che l'oggetto non venga n� rimosso, n� cambiato di tipo prima
					// dell'esecuzione della fase.//
					retSt = GetObjIdx(phas.object,  &phasObjIdx);
					if(retSt != RT_NORMAL)
						return(retSt);
					for(j = i + 1; j < schedNum; j++){
						retCnd = retCnd = FileRead(&filePhas, j, 1, &phasCheck, sizeof(phasCheck));
						if(retCnd != R_NORMAL)
							return(RT_FAILED);
						if(phasCheck.tecCycIdx == 0){
							//Se la fase non corrisponde a un ciclo tecnologico potrebbe essere 
							//una DECL o una REMO...//
							if((!_tcscmp(phas.object, phasCheck.object)) && ((!_tcscmp(phas.cmd_type, MAC_REMO)) || (!_tcscmp(phas.cmd_type, MAC_DECL)))){
								objMoved = true;
								break;
							}
						}
						else{
							if((phasCheck.SV_X == svx) && (phasCheck.SV_Y == svy) && (!_tcscmp(phas.object, phasCheck.object))){
								objMoved = true;
								break;
							}
						}
					}
					if(!objMoved){
						retSt = GetObjIdx(phas.object, objIdx);
						if(retSt != RT_NORMAL)
							return(retSt);
						return(RT_NORMAL);
					}
				}
				else{
				//Se i tipi di oggetti non corrispondono controllo se ci sono delle declare di mezzo...//
				
			
				}
			}
		}
		else{
			if((phas.SV_X == svx) && (phas.SV_Y == svy) && (!_tcscmp(phas.cmd_type, MAC_INSR))){
				retSt = GetObjIdx(phas.object, objIdx);
				if(retSt != RT_NORMAL)
					return(retSt);
				//Controllo che l'oggetto nno venga n� rimosso, n� cambiato di tipo.//
				objMoved = false;
				for(j = i + 1; j < schedNum; j++){
					retCnd = retCnd = FileRead(&filePhas, j, 1, &phasCheck, sizeof(phasCheck));
					if(retCnd != R_NORMAL)
						return(RT_FAILED);
					if(phasCheck.tecCycIdx == 0){
						//Se la fase non corrisponde a un ciclo tecnologico potrebbe essere 
						//una DECL o una REMO...//
						if((!_tcscmp(phas.object, phasCheck.object)) && ((!_tcscmp(phas.cmd_type, MAC_REMO)) || (!_tcscmp(phas.cmd_type, MAC_DECL)))){
							objMoved = true;
							break;
						}
					}
					else{
						if((phasCheck.SV_X == svx) && (phasCheck.SV_Y == svy) && (!_tcscmp(phas.object, phasCheck.object))){
							objMoved = true;
							break;
						}
					}
				}
				return(RT_NORMAL);
			}
		}
	}
	
	//Controllo che nella cella di destinazione non vengano inseriti oggetti prima dell'esecuzione.//
	for(i = schedNum - 1; i > 0; i--){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if((retCnd != R_NORMAL) || (phas.phase == 0))
			return(RT_FAILED);
		if(phas.tecCycIdx != 0){
			if((phas.DV_X == dvx) && (phas.DV_Y == dvy)){
				objInDest = true;
				for(j = i; j < schedNum; j++){
					retCnd = FileRead(&filePhas, j, 1, &phasCheck, sizeof(phasCheck));
					if((retCnd != R_NORMAL) || (phasCheck.phase == 0))
						return(RT_FAILED);
					if(phasCheck.tecCycIdx != 0){
						if((phasCheck.SV_X == dvx) && (phasCheck.SV_Y == dvy)){
							objInDest = false;
							break;
						}
					}
					else{
						if((!_tcscmp(phasCheck.cmd_type, MAC_REMO)) && ((phasCheck.SV_X == dvx) && (phasCheck.SV_Y == dvy))){
							objInDest = false;
							break;
						}
					}
				}
			}
		}
	}

	if(objInDest)
		return(RT_FAILED);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtIdxFromDescription
**
** Description:		Get Object Type Idx using Object Type Description
**
** Input:			Descr		- Object Type Description
** Output:			ObjtIdx		- Object Type Idx
**
** Return:			RETSTAT		- RT_NORMAL	If Object Type exist
**								- RT_INVOBJT	If invalid Object Type Idx
**								- RT_FAILED	If Object Type not exist
** Modificata per utilizzo su NT.
*/
RETSTAT GetObjtIdxFromDescription(TCHAR *Descr, GENIDX *ObjtIdx){
  RETCOND	stat;
  t_obj_type	objt;
  int		i;
  FILEIDX	file;

  file.num = F_OBJT;

  *ObjtIdx = 0;

  if (!_tcscmp(Descr, _T("")))
    return (RT_INVOBJT);

  for(i = 1; i <= N_MAX_OBJT; i++){
	  stat = FileRead( &file, i, 1, &objt, sizeof(t_obj_type) );
	  if ( stat != R_NORMAL )
		return (RT_INVOBJT);

	  if ( !_tcscmp( objt.obj_descr, Descr ) ){
		  *ObjtIdx = objt.idx;
		  return(RT_NORMAL);
	  }
	}
	
  return (RT_FAILED);

}

/*------------------------------------------------------------------------------
** Function:		GetMicrDescr
**
** Description:		Retrieve micro operation description
**
** Input:			name		- micro command name
** Output:			descr		- micro command description
**
** Return:			RETSTAT		- RT_NORMAL	If descr has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetMicrDescr(MIC_CMDNAME name, MIC_CMDDESC descr){
	RETCOND			retCnd;
	FILEIDX			fileMicr;
	t_micro_cmd		micr;
	int				i;
	
	fileMicr.num = F_MICR;

	for(i = 1; i <= N_MAX_MIC_CMD; i++){
		retCnd = FileRead(&fileMicr, i, 1, &micr, sizeof(micr));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(micr.name, name)){
			_tcscpy_s(descr,sizeof(descr), micr.descr);
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMicrName
**
** Description:		Retrieve micro operation name
**
** Input:			name		- micro command description
** Output:			descr		- micro command name
**
** Return:			RETSTAT		- RT_NORMAL	If name has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetMicrName(MIC_CMDDESC descr, MIC_CMDNAME name){
	RETCOND			retCnd;
	FILEIDX			fileMicr;
	t_micro_cmd		micr;
	int				i;
	
	fileMicr.num = F_MICR;

	for(i = 1; i <= N_MAX_MIC_CMD; i++){
		retCnd = FileRead(&fileMicr, i, 1, &micr, sizeof(micr));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(micr.descr, descr)){
			_tcscpy_s(name,sizeof(name), micr.name);
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetCamp
**
** Description:		Retrieve campaign structure
**
** Output:			camp		- campaign structure
**
** Return:			RETSTAT		- RT_NORMAL	If campaign has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/

RETSTAT GetCamp(t_camp *camp){
	RETCOND		retCnd;
	FILEIDX		fileCamp;

	fileCamp.num = F_CAMP;

	retCnd = FileRead(&fileCamp, 1, 1, camp, sizeof(t_camp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetCamp
**
** Description:		Set campaign structure
**
** Input:			camp		- campaign structure
**
** Return:			RETSTAT		- RT_NORMAL	If campaign has been set
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/

RETSTAT SetCamp(t_camp *camp){
	RETCOND		retCnd;
	FILEIDX		fileCamp;

	fileCamp.num = F_CAMP;

	retCnd = FileWrite(&fileCamp, 1, 1, camp, sizeof(t_camp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitPhasFile
**
** Description:		Initialize F.PHAS DAFS file
**
** Input:			---			- ---
**
** Return:			RETSTAT		- RT_NORMAL	If fle has been initilized
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT InitPhasFile(){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	phas_struc		phas;
	int				rec;

	ZeroMemory(&phas, sizeof(phas_struc));

	fileIdx.num = F_PHAS;

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileWrite(&fileIdx, rec, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	return(RT_NORMAL);
}
	
/*------------------------------------------------------------------------------
** Function:		SetPhaseResult
**
** Description:		Set phase result
**
** Input:			phase		- phase number
**					result		- phase result
**
** Return:			RETSTAT		- RT_NORMAL	If result has been set
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/

RETSTAT SetPhaseResult(int phase, int result){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phase < 1) && (phase > N_MAX_PHASE))
		return(RT_FAILED);

	if((result < PHAS_TOEXECUTE) && (result > PHAS_INEXECUTION))
		return(RT_FAILED);

	for(rec = 1; rec < N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phase){
			phas.esito = result;
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
		else if(phas.phase == 0)
			break;
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseResult
**
** Description:		Set phase result
**
** Input:			phase		- phase number
** Output:			result		- phase result
**
** Return:			RETSTAT		- RT_NORMAL	If result has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/

RETSTAT GetPhaseResult(int phase, int *result){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phase < 1) && (phase > N_MAX_PHASE))
		return(RT_FAILED);

	*result = 0;

	for(rec = 1; rec < N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phase){
			*result = phas.esito;
			return(RT_NORMAL);
		}
		else if(phas.phase == 0)
			break;
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetCellType
**
** Description:		Retrieve cell type
**
** Input:			vx			- cell virtual X coordinate
**					vy			- cell virtual Y coordinate
** Output:			type		- type of the cell
**
** Return:			RETSTAT		- RT_NORMAL	If type has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/

RETSTAT GetCellType(short int vx, short int vy, GENIDX *type){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileCell;
	int			rec;
	GENIDX		zoneIdx;
	t_cell		cell;

	if((vx == 0) && (vy == 0))
		return(RT_FAILED);
	
	retSt = GetZoneIdxVirtCoo(vx, vy, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	fileCell.num = F_CE01 + zoneIdx - 1;

	for(rec = 1; rec <= N_MAX_CELL; rec++){
		retCnd = FileRead(&fileCell, rec, 1, &cell, sizeof(cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((cell.Virt_X == vx) && (cell.Virt_Y == vy)){
			*type = cell.type;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetCampaignTime
**
** Description:		Set the campaign start/end time
**
** Input:			flag		- 0 to set start time, 1 to set end time
**
** Return:			RETSTAT		- RT_NORMAL	If time has been set
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT SetCampaignTime(int flag){
	RETCOND		retCnd;
	FILEIDX		fileCamp;
	t_camp		camp;

	fileCamp.num = F_CAMP;

	retCnd = FileRead(&fileCamp, 1, 1, &camp, sizeof(camp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	if(flag == 0)
		GetApmsTimeEx(&camp.startTime);
	else if(flag == 1)
		GetApmsTimeEx(&camp.endTime);
	else
		return(RT_FAILED);
	retCnd = FileWrite(&fileCamp, 1, 1, &camp, sizeof(camp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseMicroOpNum
**
** Description:		Retrieve a phase micro operations' number
**
** Input:			phase		- the phase to check for number
** Output:			num			- number of micro operations
**
** Return:			RETSTAT		- RT_NORMAL	If number has been retrirved
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetPhaseMicroOpNum(int phase, int *num){
	RETCOND			retCnd;
	FILEIDX			fileMice;
	micro_cmd_exe	mice;
	int				i;
	int				counter;

	counter = 0;
	*num = counter;
	fileMice.num = F_MICE;

	for(i = 1; i <= N_MAX_MICENR; i++){
		retCnd = FileRead(&fileMice, i, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice.phase == phase)
			counter++;
	}
	*num = counter;
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseTecCyc
**
** Description:		Retrieve a phase micro operations' number
**
** Input:			phase		- phase number
** Output:			tecCyc		- technological cycle structure
**
** Return:			RETSTAT		- RT_NORMAL	If tecCyc has been retrirved
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetPhaseTecCyc(int phase, t_teccyc *tecCyc){
	RETCOND			retCnd;
	RETSTAT			retSt;
	FILEIDX			filePhas;
	phas_struc		phas;
	TECCYCID		tcId;
	int				i;

	filePhas.num = F_PHAS;

	for(i = 1; i <= N_MAX_PHASE; i++){
		retCnd = FileRead(&filePhas, i, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phase){
			if(phas.tecCycIdx != 0){
				retSt = GetTechCycId(phas.tecCycIdx, tcId);
				if(retSt != RT_NORMAL)
					return(retSt);
				retSt = GetTechCyc(tcId, tecCyc);
				if(retSt != RT_NORMAL)
					return(retSt);
				return(RT_NORMAL);
			}
			else
				return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetObjtDescrFromName
**
** Description:		Retrieve an object type description
**
** Input:			objtName	- object type name
** Output:			Descr		- object type description
**
** Return:			RETSTAT		- RT_NORMAL	If Descr has been retrirved
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetObjtDescrFromName(OBJTNAME objtName, TCHAR *Descr){
	RETSTAT		retSt;
	GENIDX		objtIdx;

	retSt = GetObjtIdx(objtName, &objtIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetObjtDescription(objtIdx, Descr);
	if(retSt != RT_NORMAL)
		return(retSt);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetMiceStatus
**
** Description:		Set a micro operation execution status
**
** Input:			miceIndex	- Micro command execution index
**					miceExe		- Micro command execution status
**
** Return:			RETSTAT		- RT_NORMAL	If status has been set
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT SetMiceStatus(short int miceIndex, short int miceExe){
	RETCOND			retCnd;
	FILEIDX			fileMice;
	micro_cmd_exe	mice;
	int				rec;

	fileMice.num = F_MICE;

	if((miceExe < MICE_PENDING) || (miceExe > MICE_STOPPED))
		return(RT_FAILED);
	
	if((miceIndex < 1) || (miceIndex > N_MAX_MICENR)) 
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileMice, rec, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice.index == miceIndex){
			mice.exe = miceExe;
			retCnd = FileWrite(&fileMice, rec, 1, &mice, sizeof(mice));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMiceStatus
**
** Description:		Get a micro operation execution status
**
** Input:			miceIndex	- Micro command execution index
** Output:			miceExe		- Micro command execution status
**
** Return:			RETSTAT		- RT_NORMAL	If status has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetMiceStatus(short int miceIndex, short int *miceExe){
	RETCOND			retCnd;
	FILEIDX			fileMice;
	micro_cmd_exe	mice;
	int				rec;

	fileMice.num = F_MICE;

	*miceExe = 0;
	
	if((miceIndex < 1) || (miceIndex > N_MAX_MICENR)) 
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileMice, rec, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice.index == miceIndex){
			*miceExe = mice.exe;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseEndTime
**
** Description:		Set a phase end time
**
** Input:			phase		- phase index
**
** Return:			RETSTAT		- RT_NORMAL	If time has been set
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT SetPhaseEndTime(int phase){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;
	
	if((phase < 1) || (phase > N_MAX_PHASE))
		return(RT_FAILED);

	filePhas.num = F_PHAS;

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phase){
			retCnd = GetApmsTimeEx(&phas.end_phse_time);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseBreakTime
**
** Description:		Set a phase break time
**
** Input:			phase		- phase index
**
** Return:			RETSTAT		- RT_NORMAL	If time has been set
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT SetPhaseBreakTime(int phase){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;
	
	if((phase < 1) || (phase > N_MAX_PHASE))
		return(RT_FAILED);

	filePhas.num = F_PHAS;

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phase){
			retCnd = GetApmsTimeEx(&phas.brk_phse_time);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetLoggedUserLevel
**
** Description:		Retrieve current logged user security level.
**
** Input			opStation	- Client operation station number
** Output			level		- Security level
**
** Return:			RETSTAT		- RT_NORMAL	If condition has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetLoggedUserLevel(DWORD opStation, int *level){
	int			secLevel, secGroup;
	int			ret;

	*level = -1;

	ret = CheckSecurity(opStation, TNTPRIV_TAGMONITOR, SYSMGR_SECLEV, SYSMGR_SECGRO);
	if(ret == 1){
		*level = SYSMGR;
		return RT_NORMAL;
	}
	
	for(secLevel = LEVEL5_SECLEV; secLevel <= LEVEL1_SECLEV; secLevel++){
		switch(secLevel){
		case LEVEL1_SECLEV:
			secGroup = LEVEL1_SECGRO;
			break;
		case LEVEL2_SECLEV:
			secGroup = LEVEL2_SECGRO;
			break;
		case LEVEL3_SECLEV:
			secGroup = LEVEL3_SECGRO;
			break;
		case LEVEL4_SECLEV:
			secGroup = LEVEL4_SECGRO;
			break;
		case LEVEL5_SECLEV:
			secGroup = LEVEL5_SECGRO;
			break;
		}
		ret = CheckSecurity(opStation, TNTPRIV_VIEWDISPLAY, secLevel, secGroup);
		if(ret == 1){
			*level = secGroup;
			return RT_NORMAL;
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTCOpSeq
**
** Description:		Retrieve a Technological Cycle Operation Sequence
**
** Input			tcId		- Technological Cycle Id
** Output			tcSeq		- Technological Cycle Operation Sequence
**
** Return:			RETSTAT		- RT_NORMAL	If sequence has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetTCOpSeq(TECCYCID tcId, tc_seq *tcSeq){
	RETSTAT		retSt;
	RETCOND		retCnd;
	t_teccyc	tc;
	int			rec;
	FILEIDX		fileTseq;

	fileTseq.num = F_TSEQ;

	retSt = GetTechCyc(tcId, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(rec = 1; rec <= N_MAX_TECC; rec++){
		retCnd = FileRead(&fileTseq, rec, 1, tcSeq, sizeof(tc_seq));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(tcSeq->techCycIdx == tc.idx)
			return(RT_NORMAL);
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTCOpSeqCoordinates
**
** Description:		Retrieve a Technological Cycle Operation Sequence Coordinates
**
** Input			tcIdx		- Technological Cycle Idx
**					seqNum		- Operation to retrieve coordinates (zero based)
** Output			vx			- Virtual Coordinate X
**					vy			- Virtual Coordinate Y
**
** Return:			RETSTAT		- RT_NORMAL	If sequence has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetTCOpSeqCoordinates(GENIDX tcIdx, int seqNum, short int *vx, short int *vy){
	RETSTAT			retSt;
	RETCOND			retCnd;
	TECCYCID		tcId;
	tc_seq			tcSeq;
	int				currPhas;
	phas_struc		phas;
	FILEIDX			filePhas;
	GENIDX			zoneIdx;
	bool			isMove;
	int				i;

	filePhas.num = F_PHAS;
	
	retSt = GetDynCurrentPhase(&currPhas);
	if(retSt != RT_NORMAL)
		return(retSt);
	retCnd = FileRead(&filePhas, currPhas, 1, &phas, sizeof(phas));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	retSt = GetTechCycId(tcIdx, tcId);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetTCOpSeq(tcId, &tcSeq);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(seqNum > tcSeq.numOp)
		return(RT_FAILED);

	if(!_tcscmp(tcSeq.seq[seqNum].opType, _T("MOVE")))
		isMove = true;
	else
		isMove = false;

	if(isMove){
		if((!_tcscmp(tcSeq.seq[seqNum].par_1, _T("SVX"))) && (!_tcscmp(tcSeq.seq[seqNum].par_2, _T("SVY")))){
			*vx = phas.SV_X;
			*vy = phas.SV_Y;
			return(RT_NORMAL);
		}
		else if((!_tcscmp(tcSeq.seq[seqNum].par_1, _T("DVX"))) && (!_tcscmp(tcSeq.seq[seqNum].par_2, _T("DVY")))){
			*vx = phas.DV_X;
			*vy = phas.DV_Y;
			return(RT_NORMAL);
		}
		else if((!_tcscmp(tcSeq.seq[seqNum].par_1, _T("CC_VX"))) && (!_tcscmp(tcSeq.seq[seqNum].par_2, _T("CC_VY")))){
			*vx = CLUS_CAS_VX;
			*vy = CLUS_CAS_VY;
			return(RT_NORMAL);
		}
		else if((!_tcscmp(tcSeq.seq[seqNum].par_1, _T("HECA_SEAT_VX"))) && (!_tcscmp(tcSeq.seq[seqNum].par_2, _T("HECA_SEAT_VY")))){
			*vx = phas.HECA_INT_VX;
			*vy = phas.HECA_INT_VY;
			retSt = GetZoneIdxVirtCoo(*vx, *vy, &zoneIdx);
			if(retSt != RT_NORMAL)
				return (RT_FAILED);
			return(RT_NORMAL);
		}
		else if((!_tcscmp(tcSeq.seq[seqNum].par_1, _T("FFDS_SEAT_VX"))) && (!_tcscmp(tcSeq.seq[seqNum].par_2, _T("FFDS_SEAT_VY")))){
			*vx = phas.FFDS_INT_VX;
			*vy = phas.FFDS_INT_VY;
			retSt = GetZoneIdxVirtCoo(*vx, *vy, &zoneIdx);
			if(retSt != RT_NORMAL)
				return (RT_FAILED);
			return(RT_NORMAL);
		}
		else{
			*vx = (short int)(_ttoi(tcSeq.seq[seqNum].par_1));
			*vy = (short int)(_ttoi(tcSeq.seq[seqNum].par_2));
			//Controllo che la cella esista//
			retSt = GetZoneIdxVirtCoo(*vx, *vy, &zoneIdx);
			if(retSt != RT_NORMAL)
				return (RT_FAILED);
			return(RT_NORMAL);
		}
		return(RT_FAILED);
	}
	else{
		for(i = 1; i <= seqNum; i++){
			if(!_tcscmp(tcSeq.seq[seqNum - i].opType, _T("MOVE"))){
				if((!_tcscmp(tcSeq.seq[seqNum - i].par_1, _T("SVX"))) && (!_tcscmp(tcSeq.seq[seqNum - i].par_2, _T("SVY")))){
				*vx = phas.SV_X;
				*vy = phas.SV_Y;
				return(RT_NORMAL);
				}
				else if((!_tcscmp(tcSeq.seq[seqNum - i].par_1, _T("DVX"))) && (!_tcscmp(tcSeq.seq[seqNum - i].par_2, _T("DVY")))){
					*vx = phas.DV_X;
					*vy = phas.DV_Y;
					return(RT_NORMAL);
				}
				else if((!_tcscmp(tcSeq.seq[seqNum - i].par_1, _T("CC_VX"))) && (!_tcscmp(tcSeq.seq[seqNum - i].par_2, _T("CC_VY")))){
					*vx = CLUS_CAS_VX;
					*vy = CLUS_CAS_VY;
					return(RT_NORMAL);
				}
				else if((!_tcscmp(tcSeq.seq[seqNum - i].par_1, _T("HECA_SEAT_VX"))) && (!_tcscmp(tcSeq.seq[seqNum - i].par_2, _T("HECA_SEAT_VY")))){
					*vx = phas.HECA_INT_VX;
					*vy = phas.HECA_INT_VY;
					retSt = GetZoneIdxVirtCoo(*vx, *vy, &zoneIdx);
					if(retSt != RT_NORMAL)
						return (RT_FAILED);
					return(RT_NORMAL);
				}
				else if((!_tcscmp(tcSeq.seq[seqNum - i].par_1, _T("FFDS_SEAT_VX"))) && (!_tcscmp(tcSeq.seq[seqNum - i].par_2, _T("FFDS_SEAT_VY")))){
					*vx = phas.FFDS_INT_VX;
					*vy = phas.FFDS_INT_VY;
					retSt = GetZoneIdxVirtCoo(*vx, *vy, &zoneIdx);
					if(retSt != RT_NORMAL)
						return (RT_FAILED);
					return(RT_NORMAL);
				}
				else{
					*vx = (short int)(_ttoi(tcSeq.seq[seqNum - i].par_1));
					*vy = (short int)(_ttoi(tcSeq.seq[seqNum - i].par_2));
					//Controllo che la cella esista//
					retSt = GetZoneIdxVirtCoo(*vx, *vy, &zoneIdx);
					if(retSt != RT_NORMAL)
						return (RT_FAILED);
					return(RT_NORMAL);
				}
			}
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetDynStruc
**
** Description:		Read dynamic structure from F.DYNP DAFS file
**
** Output			dyn			- dynamic structure
**
** Return:			RETSTAT		- RT_NORMAL	If dynamic structure has been found
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetDynStruc(dynamic_struc *dyn){
	RETCOND		retCnd;
	FILEIDX		fileDynp;

	fileDynp. num = F_DYNP;

	retCnd = FileRead(&fileDynp, 1, 1, dyn, sizeof(dynamic_struc));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDynStruc
**
** Description:		Write dynamic structure on F.DYNP DAFS file
**
** Input			dyn			- dynamic structure
**
** Return:			RETSTAT		- RT_NORMAL	If dynamic structure has been written
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT SetDynStruc(dynamic_struc dyn){
	RETCOND		retCnd;
	FILEIDX		fileDynp;

	fileDynp. num = F_DYNP;

	retCnd = FileWrite(&fileDynp, 1, 1, &dyn, sizeof(dynamic_struc));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitMoveBuffer
**
** Description:		Initaialize Movement Buffer DAFS file (F.MBUF)
**
** Return:			RETSTAT		- RT_NORMAL	If file has been initialized
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitMoveBuffer(){
	RETCOND			retCnd;
	FILEIDX			fileMbuf;
	move_buffer		movBuf;
	int				rec;

	fileMbuf.num = F_MBUF;

	movBuf.vx = 0;
	movBuf.vy = 0;

	for(rec = 1; rec <= N_MAX_MOVEBUF; rec++){
		retCnd = FileWrite(&fileMbuf, rec, 1, &movBuf, sizeof(movBuf));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		MoveBufferAppend
**
** Description:		Add an entry in Movement Buffer DAFS file.
**
** Input			movBuf		- move_buffer structure to append in file
**
** Return:			RETSTAT		- RT_NORMAL	If movement has been written.
**								- RT_FAILED	If errors occurred
*/
RETSTAT MoveBufferAppend(move_buffer movBuf){
	RETCOND			retCnd;
	RETSTAT			retSt;
	FILEIDX			fileMbuf;
	int				rec;

	fileMbuf.num = F_MBUF;
	
	retSt = FindMoveBufferLastEntry(&rec);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(rec >= N_MAX_MOVEBUF)
		return(RT_FAILED);

	retCnd = FileWrite(&fileMbuf, rec + 1, 1, &movBuf, sizeof(movBuf));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		FindMoveBufferEntry
**
** Description:		Find last saved movement regarding a cell 
**
** Input			vx			- virt x of the cell to look for
**					vy			- virt y of the cell to look for
** OutPut			moveBuf		- movement buffer structure
**
** Return:			RETSTAT		- RT_NORMAL	If movement has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT FindMoveBufferEntry(short int vx, short int vy, move_buffer *movBuf){
	RETCOND			retCnd;
	RETSTAT			retSt;
	int				rec;
	int				lastRec;
	FILEIDX			fileMbuf;

	fileMbuf.num = F_MBUF;
	
	retSt = FindMoveBufferLastEntry(&lastRec);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(lastRec > N_MAX_MOVEBUF)
		return(RT_FAILED);
	
	for(rec = lastRec; rec > 0; rec--){
		retCnd = FileRead(&fileMbuf, rec, 1, movBuf, sizeof(move_buffer));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((movBuf->vx == vx) && (movBuf->vy == vy))
			return(RT_NORMAL);
	}
	return(RT_NOTINMOVBUF);

}

/*------------------------------------------------------------------------------
** Function:		FindMoveBufferLastEntry
**
** Description:		Find last saved movement in Movemetn Buffer file
**
** Output:			rec			- Record number for the last entry in F.MBUF
**
** Return:			RETSTAT		- RT_NORMAL	If movement has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT FindMoveBufferLastEntry(int *rec){
	RETCOND			retCnd;
	FILEIDX			fileMbuf;
	move_buffer		movBuf;
	int				i;


	fileMbuf.num = F_MBUF;
	
	for(i = 1; i <= N_MAX_MOVEBUF; i++){
		retCnd = FileRead(&fileMbuf, i, 1, &movBuf, sizeof(movBuf));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((movBuf.vx == 0) && (movBuf.vy == 0)){
			*rec = i - 1;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckMoveBufferEntry
**
** Description:		Check if a object type is present in the last entry of a cell
**
** Input			vx			- virt x of the cell to look for
**					vy			- virt y of the cell to look for
**					objtIdx		- object type idx to look for in last entry of the specified 
**								  cell in the movement buffer.
** OutPut			moveBuf		- movement buffer structure
**
** Return:			RETSTAT		- RT_NORMAL	If movement has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT CheckMoveBufferEntry(short int vx, short int vy, GENIDX objtIdx, move_buffer *movBuf){
	RETCOND			retCnd;
	RETSTAT			retSt;
	int				rec;
	int				lastRec;
	int				objtGenCode;
	FILEIDX			fileMbuf;

	fileMbuf.num = F_MBUF;
	
	retSt = FindMoveBufferLastEntry(&lastRec);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	retSt = GetObjtGenericTypeCode(objtIdx, &objtGenCode);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(lastRec > N_MAX_MOVEBUF)
		return(RT_FAILED);
	
	for(rec = lastRec; rec > 0; rec--){
		retCnd = FileRead(&fileMbuf, rec, 1, movBuf, sizeof(move_buffer));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(objtIdx != -1){
			if((movBuf->vx == vx) && (movBuf->vy == vy)){
				if(movBuf->cellSituation.obj[objtGenCode] == objtIdx)
					return(RT_NORMAL);
				else
					return(RT_FAILED);
			}
		}
		else{
			if((movBuf->vx == vx) && (movBuf->vy == vy))
				return(RT_NORMAL);
			else
				return(RT_FAILED);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTCOpDescription
**
** Description:		Check if a object type is present in the last entry of a cell
**
** Input			tecCycIdx	- technological cycle indentifier
**					seqNum		- TC operation sequence number
** Output			descr		- description
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If description has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTCOpDescription(GENIDX tecCycIdx, int seqNum, TC_OP_DSC descr){
	RETCOND			retCnd;
	FILEIDX			fileTseq;
	tc_seq			tcSeq;
	int				rec;

	fileTseq.num = F_TSEQ;

	for(rec = 1; rec <= N_MAX_TC_SEQ; rec++){
		retCnd = FileRead(&fileTseq, rec, 1, &tcSeq, sizeof(tc_seq));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(tcSeq.techCycIdx == tecCycIdx){
			_stprintf_s(descr,sizeof(descr), _T("%s"), tcSeq.seq[seqNum].descr);
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTcOpStatus
**
** Description:		retrieve the complition status af a technological cycle step
**
** Input			startRec	- technological cycle step identifier
**					stoprec		- 
** Output			opStatus	- operation status
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If status has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTcOpStatus(int startRec, int stopRec, int *opStatus){
	RETCOND			retCnd;
	FILEIDX			fileMice;
	micro_cmd_exe	mice;
	int				rec;

	fileMice.num = F_MICE;

	for(rec = startRec; rec <= stopRec; rec++){
		retCnd = FileRead(&fileMice, rec, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return RT_FAILED;
		if(mice.phase == 0)
			break;
		if(mice.exe == MICE_PENDING)
			*opStatus = MICE_PENDING;
		else if(mice.exe == MICE_SUCCESS)
			*opStatus = MICE_SUCCESS;
		else if(mice.exe == MICE_INPROGR){
			*opStatus = MICE_INPROGR;
			return(RT_NORMAL);
		}
		else if(mice.exe == MICE_FAILED){
			*opStatus = MICE_FAILED;
			return(RT_NORMAL);
		}
		else if(mice.exe == MICE_BREAK){
			*opStatus = MICE_BREAK;
			return(RT_NORMAL);
		
		}
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTcSDFlag
**
** Description:		Retrieve a technological cycle Source/destination flag
**
** Input			tecCycIdx	- Technological cycle Idx
**				
** Output			sdFlag		- Source/destination flag
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If flag has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTcSDFlag(GENIDX tecCycIdx, int *sdFlag){
	RETSTAT		retSt;
	t_teccyc	tc;

	retSt = GetTechCycFromIdx(tecCycIdx, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	*sdFlag = tc.sdEnabled;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTcObjFlag
**
** Description:		Retrieve a technological cycle Object flag
**
** Input			tecCycIdx	- Technological cycle Idx
**				
** Output			objFlag		- Object flag
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If flag has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTcObjFlag(GENIDX tecCycIdx, int *objFlag){
	RETSTAT		retSt;
	t_teccyc	tc;

	retSt = GetTechCycFromIdx(tecCycIdx, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	*objFlag = tc.objEnabled;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTcCondFlag
**
** Description:		Retrieve a technological cycle Condition flag
**
** Input			tecCycIdx	- Technological cycle Idx
**				
** Output			sdFlag		- Condition flag
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If flag has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTcCondFlag(GENIDX tecCycIdx, int *condFlag){
	RETSTAT		retSt;
	t_teccyc	tc;

	retSt = GetTechCycFromIdx(tecCycIdx, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	*condFlag = tc.condEnabled;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTcContIdx
**
** Description:		Retrieve a technological cycle required container IDx
**
** Input			tecCycIdx	- Technological cycle Idx
**				
** Output			contIdx		- Contaier Identifier
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If contIdx has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTcContIdx(GENIDX tecCycIdx, int *contIdx){
	RETSTAT		retSt;
	t_teccyc	tc;

	retSt = GetTechCycFromIdx(tecCycIdx, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	*contIdx = tc.contIdx;

	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		GetZoneIdxMT
**
** Description:		Retrieve a zone Idx starting from phys coordinates (used in MastTracker)
**
** Input			x			- physical x coordinates
**					y			- physical y coordinates
** Output			zoneIdx		- identifier of the zone
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If zone Idx has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetZoneIdxMT(float x, float y, GENIDX *zoneIdx){
	RETSTAT			retSt;
	t_zone			zoneIO;
	t_zone			zoneReact;
	t_zone			zoneFFDS;
	t_zone			zoneMain;
	t_zone			zoneZ212;
	GENIDX			IOZoneIdx;
	GENIDX			reactZoneIdx;
	GENIDX			FFDSZoneIdx;
	GENIDX			mainZoneIdx;
	GENIDX			Z212Idx;

	retSt = GetZoneIdx(ZONE_IO, &IOZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(IOZoneIdx, &zoneIO);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_REACTOR, &reactZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(reactZoneIdx, &zoneReact);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_FFDS, &FFDSZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(FFDSZoneIdx, &zoneFFDS);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_MAIN, &mainZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(mainZoneIdx, &zoneMain);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_FA_02, &Z212Idx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(Z212Idx, &zoneZ212);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(x >= zoneReact.zone_coord.L_H_CooX - (float)(TOLL_MM)){
		*zoneIdx = reactZoneIdx;
		return(RT_NORMAL);
	}
	else if((x > zoneMain.zone_coord.R_L_CooX + (float)(TOLL_MM)) && (x < zoneReact.zone_coord.L_H_CooX - (float)(TOLL_MM))){
		*zoneIdx = ZONE_C23_IDX;
		return(RT_NORMAL);

	}
	
	if((x > zoneIO.zone_coord.R_L_CooX - (float)(TOLL_MM)) && (x < zoneZ212.zone_coord.L_H_CooX + (float)(TOLL_MM)) && (y > zoneFFDS.zone_coord.L_H_CooY - (float)(TOLL_MM))){
		*zoneIdx = ZONE_C12_IDX;
		return(RT_NORMAL);
	}
	else if((x <= zoneIO.zone_coord.R_L_CooX + (float)(TOLL_MM)) && (y >= zoneIO.zone_coord.R_L_CooY + (float)(TOLL_MM))){
		*zoneIdx = IOZoneIdx;
		return(RT_NORMAL);
	}

	retSt = GetZoneIdxPhisCoo(x, y, zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseStatus
**
** Description:		Retrieve a phase execution status
**
** Input			phasNum		- phase number
** Output			status		- phase status
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If status has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseStatus(int phasNum, int *status){
	RETCOND		retCnd;
	phas_struc	phas;
	FILEIDX		filePhas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phasNum < 1) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);
	
	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phasNum){
			*status = phas.esito;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseStatus
**
** Description:		Set a phase execution status
**
** Input			phasNum		- phase number
**					status		- phase status
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If status has been set.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetPhaseStatus(int phasNum, int status){
	RETCOND		retCnd;
	phas_struc	phas;
	FILEIDX		filePhas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phasNum < 1) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);

	if((status < PHAS_TOEXECUTE) || (status > PHAS_SUSPENDED))
		return(RT_FAILED);
	
	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phasNum){
			phas.esito = status;
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseConfirmStatus
**
** Description:		Retrieve a phase confirmation status
**
** Input			phasNum		- phase number
** Output			phConf		- phase confirmation structure
**								  
**
** Return:			RETSTAT		- RT_NORMAL	If status has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseConfirmStatus(int phasNum, confStruct *phConf){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	int			rec;
	phas_struc	phas;

	filePhas.num = F_PHAS;

	for(rec = 1; rec < N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phasNum){
			memcpy(phConf, &phas.phConf, sizeof(confStruct));
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseConfirmStatus
**
** Description:		Set a phase confirmation status
**
** Input			phasNum		- phase number
**					userName	- physic user name
**								  
** Return:			RETSTAT		- RT_NORMAL	If status has been set.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetPhaseConfirmStatus(int phasNum, TCHAR userName[SZUNAM + 1]){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		filePhas;
	int			rec;
	phas_struc	phas;
	GENIDX		opIdx;

	filePhas.num = F_PHAS;

	retSt = GetUserIdxFromName(userName, &opIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	for(rec = 1; rec < N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == phasNum){
			phas.phConf.userIdx = opIdx;
			retCnd = GetApmsTimeEx(&phas.phConf.confTime);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			phas.phConf.confFlag = true;
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			else
				return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycCondNum
**
** Description:		Retrieve the number of condition requested for a TEch Cycle
**
** Input			tecCycIdx		- Tech. Cycle identifier
** Output			numCond			- number of conditions
**								  
** Return:			RETSTAT			- RT_NORMAL	If number of conditionshas been retrieved.
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetTechCycCondNum(GENIDX tecCycIdx, int *numCond){
	RETSTAT		retSt;
	t_teccyc	tc;
	TECCYCID	tcId;
	
	retSt = GetTechCycId(tecCycIdx, tcId);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetTechCyc(tcId, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	*numCond = tc.numStartConditions;
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycCond
**
** Description:		Retrieve a Tech. Cycle condition structure
**
** Input			tecCycIdx	- Tech. Cycle identifier
**					numCond		- condition number (zero based)
** Output			cond		- condition structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If condition has been rretrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTechCycCond(GENIDX tecCycIdx, int numCond, tcStartCond *cond){
	RETCOND		retCnd;
	RETSTAT		retSt;
	t_teccyc	tc;
	TECCYCID	tcId;
	GENIDX		condIdx;
	FILEIDX		fileCond;
	int			rec;

	fileCond.num = F_COND;

	retSt = GetTechCycId(tecCycIdx, tcId);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetTechCyc(tcId, &tc);
	if(retSt != RT_NORMAL)
		return(retSt);

	condIdx = tc.startCondIdx[numCond];
	
	for(rec = 1; rec <= N_MAX_START_COND; rec++){
		retCnd = FileRead(&fileCond, rec, 1, cond, sizeof(tcStartCond));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(cond->idx == condIdx)
			return(RT_NORMAL);
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseStartFlag
**
** Description:		Retrieve a phase start conditions flag
**
** Input			phasNum		- phase number
** Output			flag		- phase start flag
**					time		- phase start conditions confirmation time
**								  
** Return:			RETSTAT		- RT_NORMAL	If flag has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseStartFlag(int phasNum, bool *flag, EXTIME *time){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phasNum <= 0) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == 0)
			break;
		else if(phas.phase == phasNum){
			*flag = phas.startCondFlag;
			if(phas.startCondFlag)
				*time = phas.startCondTime;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseStartFlag
**
** Description:		Set a phase start conditions flag
**
** Input			phasNum		- phase number
**					flag		- phase start flag
**								  
** Return:			RETSTAT		- RT_NORMAL	If flag has been set.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetPhaseStartFlag(int phasNum, bool flag){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phasNum <= 0) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == 0)
			break;
		else if(phas.phase == phasNum){
			phas.startCondFlag = flag;
			if(flag){
				retCnd = GetApmsTimeEx(&phas.startCondTime);
				if(retCnd != R_NORMAL)
					return(RT_FAILED);
			}
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas_struc));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseStartCond
**
** Description:		Set a phase start conditions 
**
** Input			phasNum		- phase number
** Output			cond		- phase start conditions
**								  
** Return:			RETSTAT		- RT_NORMAL	If conditions have been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseStartCond(int phasNum, bool *cond[N_COND_PER_TC]){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;
	int			i;

	filePhas.num = F_PHAS;

	if((phasNum <= 0) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == 0)
			break;
		else if(phas.phase == phasNum){
			if(phas.startCondFlag){
				for(i = 0; i < 	N_COND_PER_TC; i++)
					*cond[i] = phas.startCond[i];
			}
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseSingleStartCond
**
** Description:		Set a phase start conditions 
**
** Input			phasNum		- phase number
**					numCond		- condition number (zero based).
**					cond		- phase start conditions
**								  
** Return:			RETSTAT		- RT_NORMAL	If condition has been set.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetPhaseSingleStartCond(int phasNum, int numCond, bool cond){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;
	
	filePhas.num = F_PHAS;

	if((phasNum <= 0) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);

	if((numCond < 0) || (numCond > N_COND_PER_TC))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == 0)
			break;
		else if(phas.phase == phasNum){
			phas.startCond[numCond] = cond;
			retCnd = FileWrite(&filePhas, rec, 1, &phas, sizeof(phas_struc));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseSingleStartCond
**
** Description:		Retrieve a phase start condition
**
** Input			phasNum		- phase number
**					numCond		- condition number (0 based)
**					cond		- phase start conditions
**								  
** Return:			RETSTAT		- RT_NORMAL	If condition has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseSingleStartCond(int phasNum, int numCond, bool *cond){
	RETCOND		retCnd;
	FILEIDX		filePhas;
	phas_struc	phas;
	int			rec;

	filePhas.num = F_PHAS;

	if((phasNum <= 0) || (phasNum > N_MAX_PHASE))
		return(RT_FAILED);

	if((numCond < 0) || (numCond > N_COND_PER_TC))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&filePhas, rec, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas.phase == 0)
			break;
		else if(phas.phase == phasNum){
			*cond = phas.startCond[numCond];
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetPhase
**
** Description:		Retrieve a phase structure
**
** Input			phasNum		- phase number
** Output			phas		- phas structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If phas has been retrieved.
**								- RT_INVPHAS If phas hasn't been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetPhase(int phasNum, phas_struc *phas){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	int			rec;

	fileIdx.num = F_PHAS;

	if((phasNum <= 0) || (phasNum > N_MAX_PHASE))
		return RT_FAILED;

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(phas->phase == 0)
			break;
		else if(phas->phase == phasNum)
			return(RT_NORMAL);
	}
	return(RT_INVPHAS);
}

/*------------------------------------------------------------------------------
** Function:		SetPhase
**
** Description:		Set a phase structure
**
** Input			phas		- phas structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If phas has been set.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetPhase(phas_struc phas){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	phas_struc	dummy;
	int			rec;

	fileIdx.num = F_PHAS;

	for(rec = 1; rec <= N_MAX_PHASE; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &dummy, sizeof(phas_struc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(dummy.phase == 0)
			break;
		else if(dummy.phase == phas.phase){
			retCnd = FileWrite(&fileIdx, rec, 1, &phas, sizeof(phas_struc));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		InitSSTRFile
**
** Description:		Initialize SSTR DAFS file
**								  
** Return:			RETSTAT		- RT_NORMAL	If file has been initialized.
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitSSTRFile(void){
	RETCOND		retCnd;
	FILEIDX		fileSstr;
	int			rec;
	TCHAR		temp[SSTR_STR_LEN];

	fileSstr.num = F_SSTR;
	_stprintf_s(temp, _T(""));

	for(rec = 1; rec <= N_MAX_STR; rec++){
		retCnd = FileWrite(&fileSstr, rec, 1, temp, sizeof(temp));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		SetSSTREntry
**
** Description:		Set a string in SSTR DAFS file
**
** Input			strPos		- record where the string must be inserted
**					str			- string to be inserted
**								  
** Return:			RETSTAT		- RT_NORMAL	If string has been inserted.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetSSTREntry(int strPos, TCHAR *str){
	RETCOND		retCnd;
	FILEIDX		fileSstr;
	TCHAR		temp[SSTR_STR_LEN];
	
	fileSstr.num = F_SSTR;
	
	if((strPos <= 0) || (strPos > N_MAX_STR))
		return(RT_FAILED);

	_tcscpy_s(temp, str);

	retCnd = FileWrite(&fileSstr, strPos, 1, temp, sizeof(temp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		GetSSTREntry
**
** Description:		Retrieve a string from DAFS file SSTR
**
** Input			strPos		- string number to be retrieved
** Output			str			- string found
**								  
** Return:			RETSTAT		- RT_NORMAL	If str has been retrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetSSTREntry(int strPos, TCHAR *str){
	RETCOND		retCnd;
	FILEIDX		fileSstr;
	TCHAR		temp[SSTR_STR_LEN];

	fileSstr.num = F_SSTR;
	
	if((strPos <= 0) || (strPos > N_MAX_STR))
		return(RT_FAILED);

	retCnd = FileRead(&fileSstr, strPos, 1, temp, sizeof(temp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	_tcscpy_s(str,sizeof(str), temp);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetSSTREntryEx
**
** Description:		Set a string in SSTR DAFS file
**
** Input			infoNum		- index of the info to set in SSTR DAFS file
**					currOp		- name of the current macro operation
**								  
** Return:			RETSTAT		- RT_NORMAL	If str has been set.
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetSSTREntryEx(int infoNum, micro_cmd_exe *currOp){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileSstr;
	TCHAR		temp[SSTR_STR_LEN];
	int			currPhas;
	short int	svx;
	short int	svy;
	short int	dvx;
	short int	dvy;
	OBJNAME		objName;
	OBJTNAME	objtName;
	t_teccyc	tecCyc;
    TCHAR 		objtDescr[MAX_OBJ_DESCR];
    TCHAR 		svCoord[32];
	TCHAR		dvCoord[32];
	TC_OP_DSC	tcOpDescr;
	phas_struc	phas;	
	
	fileSstr.num = F_SSTR;
	
	if(((infoNum == SSTR_MECH_REC) ||(infoNum == SSTR_TCSEQ_REC)) && (currOp == NULL))
		return(RT_FAILED);

	retSt = GetDynCurrentPhase(&currPhas);
	if(retSt != RT_NORMAL)
		return(retSt);
	if(currPhas != 0){
		retSt = GetPhase(currPhas, &phas);
		if(retSt != RT_NORMAL)
			return(retSt);
	}
	
	if(phas.tecCycIdx == 0){
		switch(infoNum){
		case SSTR_TC_REC:
			if(currPhas != 0){
				if(!_tcscmp(phas.cmd_type, MAC_INSR))
					_stprintf_s(temp, _T("Database Insert operation"));
				else if(!_tcscmp(phas.cmd_type, MAC_DECL))
					_stprintf_s(temp, _T("Database Declare operation"));
				else if(!_tcscmp(phas.cmd_type, MAC_REMO))
					_stprintf_s(temp, _T("Database Remove operation"));
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_MECH_REC:
			if(currPhas != 0)
				_stprintf_s(temp, _T(""));
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_COORD_REC:
			if(currPhas != 0){
				retSt = GetPhaseSourceVirtCoo(currPhas, &svx, &svy);
				if(retSt != RT_NORMAL)
					return(retSt);
				_stprintf_s(temp, _T("(%d,%d)"), svx, svy);
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_OBJ_REC:
			if(currPhas != 0){
				retSt = GetPhaseObjectName(currPhas, objName);
				if(retSt != RT_NORMAL)
					_stprintf_s(objName, _T("Unknown object"));
				retSt = GetPhaseObjtName(currPhas, objtName);
				if(retSt != RT_NORMAL)
					_stprintf_s(objtDescr, _T("Unknown object type"));
				else{
					retSt = GetObjtDescrFromName(objtName, objtDescr);
					if(retSt != RT_NORMAL)
						return(retSt);
				}
				_stprintf_s(temp, _T("%s, %s"), objName, objtDescr);
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_TCSEQ_REC:
			if(currPhas != 0){
				_stprintf_s(temp, _T(""));
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		}
	}
	else{
		switch(infoNum){
		case SSTR_TC_REC:
			if(currPhas != 0){
				retSt = GetPhaseTecCyc(currPhas, &tecCyc);
				if(retSt != RT_NORMAL)
					return(retSt);
				_stprintf_s(temp, _T("%s - %s"), tecCyc.id, tecCyc.descr);
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_MECH_REC:
			if(currPhas != 0){
				if(!_tcscmp(currOp->cmovet, MICRO_MOVEX))
					_stprintf_s(temp, _T("Bridge"));
				else if(!_tcscmp(currOp->cmovet, MICRO_MOVEY))
					_stprintf_s(temp, _T("Trolley"));
				else if(!_tcscmp(currOp->cmovet, MICRO_MOVEXY))
					_stprintf_s(temp, _T("Bridge, Trolley"));
				else if(!_tcscmp(currOp->cmovet, MICRO_MOVE_FAGR_MM))
					_stprintf_s(temp, _T("Main Mast FA Gripper"));
				else if(!_tcscmp(currOp->cmovet, MICRO_MOVE_CLGR_MM))
					_stprintf_s(temp, _T("Main Mast Cluster Gripper"));
				else if(!_tcscmp(currOp->cmovet, MICRO_MOVE_FAGRL_MM))
					_stprintf_s(temp, _T("Main Mast FA Gripper Latch"));
				else if(!_tcscmp(currOp->cmovet, MICRO_ROT_MM))
					_stprintf_s(temp, _T("Main Mast Rotation"));
				else if(!_tcscmp(currOp->cmovet, MICRO_MOV_TV))
					_stprintf_s(temp, _T("TV Movement"));
				else if(!_tcscmp(currOp->cmovet, MICRO_ROT_TV))
					_stprintf_s(temp, _T("TV Rotation"));
				else if(!_tcscmp(currOp->cmovet, MICRO_CTRL_OP))
					_stprintf_s(temp, _T("FA Control"));
				else if(!_tcscmp(currOp->cmovet, MICRO_DISP_MM))
					_stprintf_s(temp, _T("FA displacing movement"));
				else
					_stprintf_s(temp, _T("Unknown"));
				break;
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_COORD_REC:
			if(currPhas != 0){
				retSt = GetPhaseSourceVirtCoo(currPhas, &svx, &svy);
				if(retSt != RT_NORMAL)
					_stprintf_s(svCoord, _T("(---,---)"));
				else
					_stprintf_s(svCoord, _T("(%d,%d)"), svx, svy);

				retSt = GetPhaseDestVirtCoo(currPhas, &dvx, &dvy);
				if(retSt != RT_NORMAL)
					_stprintf_s(dvCoord, _T("(---,---)"));
				else 
					_stprintf_s(dvCoord, _T("(%d,%d)"), dvx, dvy);

				_stprintf_s(temp, _T("%s --> %s"), svCoord, dvCoord);
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_OBJ_REC:
			if(currPhas != 0){
				retSt = GetPhaseObjectName(currPhas, objName);
				if(retSt != RT_NORMAL)
					_stprintf_s(objName, _T("Unknown object"));
				retSt = GetPhaseObjtName(currPhas, objtName);
				if(retSt != RT_NORMAL)
					_stprintf_s(objtDescr, _T("Unknown object type"));
				else{
					retSt = GetObjtDescrFromName(objtName, objtDescr);
					if(retSt != RT_NORMAL)
						return(retSt);
				}
				_stprintf_s(temp, _T("%s, %s"), objName, objtDescr);
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		case SSTR_TCSEQ_REC:
			if(currPhas != 0){
				retSt = GetTCOpDescription(currOp->tecCycIdx, currOp->tcIndex, tcOpDescr);
				if(retSt != RT_NORMAL)
					return(retSt);
				_tcscpy_s(temp, tcOpDescr);
			}
			else
				_stprintf_s(temp, _T("No cycle in execution"));
			break;
		}
	}
	retCnd = FileWrite(&fileSstr, infoNum, 1, temp, sizeof(temp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		InitSSTREntry
**
** Description:		Initialize SSTR DAFS file
**								  
** Return:			RETSTAT		- RT_NORMAL	If file has been initialized.
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitSSTREntry(int entryNum){
	RETCOND		retCnd;
	FILEIDX		fileSstr;
	TCHAR		temp[SSTR_STR_LEN];

	fileSstr.num = F_SSTR;
	
	if((entryNum <= 0) || (entryNum > N_MAX_STR))
		return(RT_FAILED);

	if((entryNum == SSTR_TC_REC) || (entryNum == SSTR_COORD_REC) || (entryNum == SSTR_OBJ_REC))
		_stprintf_s(temp, _T("No Technological Cycles in progress"));
	else
		_stprintf_s(temp, _T(""));

	retCnd = FileWrite(&fileSstr, entryNum, 1, temp, sizeof(temp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		GetUserLevelFromGroup
**
** Description:		Retrieve user level from its group
**
** Input			secGroup	- security group
** Output			secLevel	- security level
**								  
** Return:			RETSTAT		- RT_NORMAL	If level has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetUserLevelFromGroup(int secGroup, int *secLevel){
	switch(secGroup){
	case LEVEL1_SECGRO:
		*secLevel = LEVEL1_SECLEV;
		return RT_NORMAL;
		break;
	case LEVEL2_SECGRO:
		*secLevel = LEVEL2_SECLEV;
		return RT_NORMAL;
		break;
	case LEVEL3_SECGRO:
		*secLevel = LEVEL3_SECLEV;
		return RT_NORMAL;
		break;
	case LEVEL4_SECGRO:
		*secLevel = LEVEL4_SECLEV;
		return RT_NORMAL;
		break;
	case LEVEL5_SECGRO:
		*secLevel = LEVEL5_SECLEV;
		return RT_NORMAL;
		break;
	case SYSMGR_SECGRO:
		*secLevel = SYSMGR_SECLEV;
		return RT_NORMAL;
	}

	return RT_FAILED;

}

/*------------------------------------------------------------------------------
** Function:		GetLoggedUserName
**
** Description:		Retrieve logged user name
**
** Input			opStation	- Client number where the user is logged
** Output			userName	- User name
**								  
** Return:			RETSTAT		- RT_NORMAL	If name has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetLoggedUserName(DWORD opStation, TCHAR userName[SZUNAM+1]){
	RETSTAT			retSt;
	RETCOND			retCnd;
	FILEIDX			filePswd;
	int				secGr;
	int				secLev;
	int				mySecLev;
	int				rec;
	TIME1090		dummyTime;
	t_pswd_record	usrRec;

	filePswd.num = F_PSWD;
	dummyTime = -1;
	secLev = 0;
	for(rec = 1; rec <= TNT_MAX_USER; rec++){
		retCnd = FileRead(&filePswd, rec, 1, &usrRec, sizeof(usrRec));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((usrRec.ipwflg.isdef) && (usrRec.ipwlln > dummyTime)){
			_stprintf_s(userName,sizeof(userName), _T("%s"), usrRec.ipwopn);
			secLev = usrRec.ipwslv;
			dummyTime = usrRec.ipwlln;
		}
	}
	
	if(secLev == -1)
		return(RT_FAILED);

	retSt = GetLoggedUserLevel(opStation, &secGr);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	retSt = GetUserLevelFromGroup(secGr, &mySecLev);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	if(mySecLev == secLev)
		return(RT_NORMAL);
	else
		return(RT_NOLOGGEDUSER);
}

/*------------------------------------------------------------------------------
** Function:		GetCurrentUserLoginTime
**
** Description:		Retrieve how long current user has been logged
**
** Input			opStation	- Client number where the user is logged
** Output			logTime		- log in time
**								  
** Return:			RETSTAT		- RT_NORMAL	If time has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetCurrentUserLoginTime(DWORD opStation, TIME1090 *logTime){
	RETCOND			retCnd;
	RETSTAT			retSt;
	FILEIDX			filePswd;
	int				rec;
	TCHAR			userName[SZUNAM+1];
	t_pswd_record	usrRec;

	filePswd.num = F_PSWD;

	retSt = GetLoggedUserName(opStation, userName);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	for(rec = 1; rec <= TNT_MAX_USER; rec++){
		retCnd = FileRead(&filePswd, rec, 1, &usrRec, sizeof(usrRec));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((usrRec.ipwflg.isdef) && (!_tcscmp(usrRec.ipwopn, userName))){
			*logTime = usrRec.ipwlln;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycFromIdx
**
** Description:		Retrieve a technological cycle stucture from its idx.
**
** Input			idx			- Technological cycle idx
** Output			tc			- Technological cycle structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If tc has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTechCycFromIdx(GENIDX idx, t_teccyc *tc){
	RETCOND		retCnd;
	FILEIDX		fileTecc;
	int			rec;

	fileTecc.num = F_TECC;

	for(rec = 1; rec <= N_MAX_TECC; rec++){
		retCnd = FileRead(&fileTecc, rec, 1, tc, sizeof(t_teccyc));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(tc->idx == idx)
			return(RT_NORMAL);
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMiceStopFlag
**
** Description:		Retrieve micro command Semiatomatic stop flag
**
** Input			miceIndex	- micro command execution index
** Output			stopFlag	- stop flag
**								  
** Return:			RETSTAT		- RT_NORMAL	If stop flag has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMiceStopFlag(short int miceIndex, int *stopFlag){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	micro_cmd_exe	mice;
	int				rec;

	fileIdx.num = F_MICE;

	if((miceIndex < 1) || (miceIndex > N_MAX_MICENR))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){	
		retCnd = FileRead(&fileIdx, rec, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice.index == miceIndex){
			if(mice.stopFlag == true)
				*stopFlag = 1;
			else
				*stopFlag = 0;
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMiceInProgr
**
** Description:		Retrieve micro command in execution
**
** Input			miceIndex	- starting operation
** Output			next		- mice in progress
**								  
** Return:			RETSTAT		- RT_NORMAL	If mice has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMiceInProgr(short int miceIndex, short int *next){
	RETSTAT			retSt;
	short int		miceStatus;
	int				rec;

	for(rec = miceIndex; rec <= N_MAX_MICENR; rec++){
		retSt = GetMiceStatus(rec, &miceStatus);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(miceStatus == MICE_INPROGR){
			*next = rec;
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMice
**
** Description:		Retrieve micro command from its index
**
** Input			miceIndex	- micro command execution index
** Output			mice		- micro command execution structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If mice has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMice(short int miceIndex, micro_cmd_exe *mice){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	int				rec;

	fileIdx.num = F_MICE;

	if((miceIndex < 1) || (miceIndex > N_MAX_MICENR))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){	
		retCnd = FileRead(&fileIdx, rec, 1, mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice->index == miceIndex){
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMastPosEx
**
** Description:		Retrieve mast dynamic position
** Input			mastType	- Mast type
** Output			px			- Mast physical X coordinate
**					py			- Mast physical Y coordinate
**								  
** Return:			RETSTAT		- RT_NORMAL	If coordinates have been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMastPosEx(GENIDX mastType, float *px, float *py){
	RETSTAT		retSt;
	
	if((mastType < MAIN_MAST) && (mastType > DMP_MAST))
		return(RT_FAILED);

	switch(mastType){
	case MAIN_MAST:
		retSt = GetDynMmxyPos(px, py);
		return(retSt);
		break;
	case FALC_MAST:
	case DMP_MAST:
		retSt = GetDynFCxyPos(px, py);
		return(retSt);
		break;
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		InitFALVFile
**
** Description:		Initialize F.FALV DAFS file
**								  
** Return:			RETSTAT		- RT_NORMAL	If initialization has been executed
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitFALVFile(void){
	RETCOND			retCnd;
	t_falv			falv;
	FILEIDX			fileIdx;
	int				rec;

	fileIdx.num = F_FALV;
	
	ZeroMemory(&falv, sizeof(t_falv));
	
	for(rec = 1; rec <= N_MAX_FALV; rec++){
		retCnd = FileWrite(&fileIdx, rec, 1, &falv, sizeof(t_falv));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitFALVRecord
**
** Description:		Initialize a FALV record
**
** Input			rec			- record to initialize
**								  
** Return:			RETSTAT		- RT_NORMAL	If initialization has been executed
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitFALVRecord(int rec){
	RETCOND			retCnd;
	t_falv			falv;
	FILEIDX			fileIdx;
	
	fileIdx.num = F_FALV;
	
	ZeroMemory(&falv, sizeof(t_falv));
	
	retCnd = FileWrite(&fileIdx, rec, 1, &falv, sizeof(t_falv));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InsertFALVRecord
**
** Description:		Insert a record in F.FALV DAFS file
**
** Input			data		- record to insert
**								  
** Return:			RETSTAT		- RT_NORMAL	If record has been inserted
**								- RT_FAILED	If errors occurred
*/
RETSTAT InsertFALVRecord(t_falv data){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileIdx;
	int			rec;

	fileIdx.num = F_FALV;
	
	retSt = FindFALVRec(data.virtX, data.virtY, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(rec == -1){
		retSt = FindFALVRec(0, 0, &rec);
		if(retSt != RT_NORMAL)
			return(retSt);
	}
	if(rec == -1)
		return(RT_FAILED);
	
	retCnd = FileWrite(&fileIdx, rec, 1, &data, sizeof(t_falv));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ReadFALVRecord
**
** Description:		Retrieve a FALV record from DAFS file F.FALV
**
** Input			virtX		- virtual X coordinate
**					virtY		- virtual Y coordinate
** Output			data		- FALV buffer structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If coordinates have been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT ReadFALVRecord(short int virtX, short int virtY, t_falv *data){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	int			rec;

	fileIdx.num = F_FALV;

	for(rec = 1; rec <= N_MAX_FALV; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, data, sizeof(t_falv));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((data->virtX == virtX) && (data->virtY == virtY)){
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		FindFALVRec
**
** Description:		Find a FALV record from DAFS file F.FALV
**
** Input			virtX		- virtual X coordinate
**					virtY		- virtual Y coordinate
** Output			recNum		- FALV buffer record number
**								  
** Return:			RETSTAT		- RT_NORMAL	If record number has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT FindFALVRec(short int virtX, short int virtY, int *recNum){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	int			rec;
	t_falv		falv;

	fileIdx.num = F_FALV;

	for(rec = 1; rec <= N_MAX_FALV; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &falv, sizeof(t_falv));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((falv.virtX == virtX) && (falv.virtY == virtY)){
			*recNum = rec;
			return(RT_NORMAL);
		}
	}
	
	*recNum = -1;
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetMiceStopFlag
**
** Description:		Set a micro command execution stop flag
**
** Input			miceIndex	- micro command execution index
**					stopFlag	- stop flag
**								  
** Return:			RETSTAT		- RT_NORMAL	If flag has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetMiceStopFlag(short int miceIndex, int stopFlag){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	micro_cmd_exe	mice;
	int				rec;

	fileIdx.num = F_MICE;

	if((miceIndex < 1) || (miceIndex > N_MAX_MICENR))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){	
		retCnd = FileRead(&fileIdx, rec, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice.index == miceIndex){
			if(stopFlag == 1)
				mice.stopFlag = true;
			else
				mice.stopFlag = false;
			retCnd = FileWrite(&fileIdx, rec, 1, &mice, sizeof(mice));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMastPosInfi
**
** Description:		Retrieve selected mast position from Infinet tag
**
** Input			mastType	- mast to retrieve position (0 - 4)
**
** Output			px			- physical X coordinate
**					py			- physical Y coordinate
**					zoneIdx		- identifier of the zone containing reaquested mast
**								  
** Return:			RETSTAT		- RT_NORMAL	If mast position has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMastPosInfi(GENIDX mastType, float *px, float *py, GENIDX *zoneIdx){
	RETCOND		retCnd;
	RETSTAT		retSt;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	float		bridgeX, trolleyY;
	float		x_off;
	float		y_off;

	bridgeX = 0.0;
	trolleyY = 0.0;

	retCnd = GetTagIdx(TWN_BRIDGE_POS, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	bridgeX = tagVal.value.val_float;
	
	retCnd = GetTagIdx(TWN_TROLLEY_POS, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	trolleyY = tagVal.value.val_float;
	
	
	switch(mastType){
	case MAIN_MAST:
		*px = bridgeX;
		*py = trolleyY;
		break;
	case FALC_MAST:
	case DMP_MAST:
		GetFALVOffset(&x_off, &y_off);
		*px = bridgeX + (float)(x_off);
		*py = trolleyY + (float)(y_off);
		break;
	case TV_MAST:
		*px = bridgeX;
		*py = trolleyY;
		break;
	}
	
	retSt = GetZoneIdxMT(*px, *py, zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetFalv
**
** Description:		Retrieve a t_falv structure from DAFS file F_FALV
**
** Input			recNum		- DAFS file record number
**
** Output			data		- t_falv saved in record recNum
**								  
** Return:			RETSTAT		- RT_NORMAL	If data has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetFalv(int recNum, t_falv *data){
	RETCOND		retCnd;
	FILEIDX		fileIdx;

	fileIdx.num = F_FALV;

	if((recNum < 1) || (recNum > N_MAX_FALV))
		return(RT_FAILED);

	retCnd = FileRead(&fileIdx, recNum, 1, data, sizeof(t_falv));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		FALVinCamp
**
** Description:		Check if a FALV operation has been esecuted in the specified campaign
**
** Input			campNum		- campaign sequence number
**					campYear	- campaign year
**
** Output			falvPresent	- FALV execution flag
**								  
** Return:			RETSTAT		- RT_NORMAL	If flag has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT FALVinCamp(int campNum, int campYear, int *falvPresent){
	RETSTAT		retSt;
	int			rec;
	t_camp		camp;
	t_falv		falv;

	retSt = GetCamp(&camp);
	if(retSt != RT_NORMAL)
		return(retSt);

	*falvPresent = 0;

	if((campYear > camp.year) || ((campYear == camp.year) && (campNum > camp.seqNum)))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_FALV; rec++){
		retSt = GetFalv(rec, &falv);
		if(retSt != RT_NORMAL)
			return(retSt);
		
		if((falv.campSeqNum == campNum) && (falv.campYear == campYear)){
			*falvPresent = 1;
			return(RT_NORMAL);
		}
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitDMPFile
**
** Description:		Initialize F.FDMP DAFS file
**								  
** Return:			RETSTAT		- RT_NORMAL	If initialization has been executed
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitDMPFile(void){
	RETCOND			retCnd;
	t_dmp			dmp;
	FILEIDX			fileIdx;
	int				rec;

	fileIdx.num = F_FDMP;
	
	ZeroMemory(&dmp, sizeof(t_dmp));
	
	for(rec = 1; rec <= N_MAX_DMP; rec++){
		retCnd = FileWrite(&fileIdx, rec, 1, &dmp, sizeof(t_dmp));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitDMPRecord
**
** Description:		Initialize a DMP record
**
** Input			rec			- record to initialize
**								  
** Return:			RETSTAT		- RT_NORMAL	If initialization has been executed
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitDMPRecord(int rec){
	RETCOND			retCnd;
	t_dmp			dmp;
	FILEIDX			fileIdx;
	
	fileIdx.num = F_FDMP;
	
	ZeroMemory(&dmp, sizeof(t_dmp));
	
	retCnd = FileWrite(&fileIdx, rec, 1, &dmp, sizeof(t_dmp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InsertDMPRecord
**
** Description:		Insert a record in F.FDMP DAFS file
**
** Input			data		- record to insert
**								  
** Return:			RETSTAT		- RT_NORMAL	If record has been inserted
**								- RT_FAILED	If errors occurred
*/
RETSTAT InsertDMPRecord(t_dmp data){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileIdx;
	int			rec;

	fileIdx.num = F_FDMP;
	
	retSt = FindDMPRec(data.virtX, data.virtY, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(rec == -1){
		retSt = FindDMPRec(0, 0, &rec);
		if(retSt != RT_NORMAL)
			return(retSt);
	}
	if(rec == -1)
		return(RT_FAILED);
	
	retCnd = FileWrite(&fileIdx, rec, 1, &data, sizeof(t_dmp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ReadDMPRecord
**
** Description:		Retrieve a DMP record from DAFS file F.FDMP
**
** Input			virtX		- virtual X coordinate
**					virtY		- virtual Y coordinate
** Output			data		- DMP buffer structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If coordinates have been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT ReadDMPRecord(short int virtX, short int virtY, t_dmp *data){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	int			rec;

	fileIdx.num = F_FDMP;

	for(rec = 1; rec <= N_MAX_DMP; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, data, sizeof(t_dmp));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((data->virtX == virtX) && (data->virtY == virtY)){
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		FindDMPRec
**
** Description:		Find a DMP record from DAFS file F.FDMP
**
** Input			virtX		- virtual X coordinate
**					virtY		- virtual Y coordinate
** Output			recNum		- DMP buffer record number
**								  
** Return:			RETSTAT		- RT_NORMAL	If record number has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT FindDMPRec(short int virtX, short int virtY, int *recNum){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	int			rec;
	t_dmp		dmp;

	fileIdx.num = F_FDMP;

	for(rec = 1; rec <= N_MAX_DMP; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &dmp, sizeof(t_dmp));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((dmp.virtX == virtX) && (dmp.virtY == virtY)){
			*recNum = rec;
			return(RT_NORMAL);
		}
	}
	
	*recNum = -1;
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetDMP
**
** Description:		Retrieve a t_dmp structure from DAFS file F_FDMP
**
** Input			recNum		- DAFS file record number
**
** Output			data		- t_dmp saved in record recNum
**								  
** Return:			RETSTAT		- RT_NORMAL	If data has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetDMP(int recNum, t_dmp *data){
	RETCOND		retCnd;
	FILEIDX		fileIdx;

	fileIdx.num = F_FDMP;

	if((recNum < 1) || (recNum > N_MAX_DMP))
		return(RT_FAILED);

	retCnd = FileRead(&fileIdx, recNum, 1, data, sizeof(t_dmp));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		DMPinCamp
**
** Description:		Check if a DMP operation has been esecuted in the specified campaign
**
** Input			campNum		- campaign sequence number
**					campYear	- campaign year
**
** Output			dmpPresent	- DMP execution flag
**								  
** Return:			RETSTAT		- RT_NORMAL	If flag has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT DMPinCamp(int campNum, int campYear, int *dmpPresent){
	RETSTAT		retSt;
	int			rec;
	t_camp		camp;
	t_dmp		dmp;

	retSt = GetCamp(&camp);
	if(retSt != RT_NORMAL)
		return(retSt);

	*dmpPresent = 0;

	if((campYear > camp.year) || ((campYear == camp.year) && (campNum > camp.seqNum)))
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_DMP; rec++){
		retSt = GetDMP(rec, &dmp);
		if(retSt != RT_NORMAL)
			return(retSt);
		
		if((dmp.campSeqNum == campNum) && (dmp.campYear == campYear)){
			*dmpPresent = 1;
			return(RT_NORMAL);
		}
	}

	return(RT_NORMAL);
}
/*------------------------------------------------------------------------------
** Function:		GetMiceFirstToExe
**
** Description:		Retrieve the index of the last completed micro-op
**
** Output			miceIndex	- micro command execution
**								  
** Return:			RETSTAT		- RT_NORMAL	If miceIndex has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMiceFirstToExe(short int *miceIndex){
	RETSTAT		retSt;
	short int	miceExe;
	int			rec;
	int			currPhas;
	int			opNum;

	retSt = GetDynCurrentPhase(&currPhas);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetPhaseMicroOpNum(currPhas, &opNum);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retSt = GetMiceStatus(rec, &miceExe);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(miceExe == MICE_PENDING){
			*miceIndex = rec;	
			return(RT_NORMAL);
		}
		if(rec == opNum){
			*miceIndex = rec;	
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetMimicCellSituation
**
** Description:		Retrieve the index of the last completed micro-op
**
** Input			mastType		- mast in use
**					cellSituation	- current situation in cell
**								  
** Return:			RETSTAT		- RT_NORMAL	If cellSituation has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetMimicCellSituation(GENIDX mastType, OBJTCELL cellSituation){
	RETCOND		retCnd;
	FILEIDX		fileMimics;
	t_cell		cell;

	fileMimics.num = F_CE30;

	if((mastType != MAIN_MAST) && (mastType != FALC_MAST) && (mastType != DMP_MAST))
		return(RT_FAILED);
	
	ZeroMemory(&cell, sizeof(t_cell));

	memcpy(&cell.objt_cell, &cellSituation, sizeof(OBJTCELL));

	if(mastType == MAIN_MAST){
		retCnd = FileWrite(&fileMimics, CELL_MM_REC, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	else{
		retCnd = FileWrite(&fileMimics, CELL_FALV_REC, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

RETSTAT SetMimicCellSituationEx(GENIDX mastType, int cellType, GENIDX zoneIdx, OBJTCELL cellSituation){
	RETSTAT		retSt;
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	GENIDX		zone1Idx;

	retCnd = GetTagIdx(TWN_U_CELL_TYPE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retSt = GetZoneIdx(ZONE_IO, &zone1Idx);
	if(retSt != RT_NORMAL)
		return(retSt);

	ZeroMemory(&tagVal, sizeof(TAGVALEX));
	tagVal.qual.b.q1imp = 1;
	switch(cellType){
	case CELL_NULL:
		tagVal.value.val_float = CELL_TYPE_NULL;
		break;
	case CELL_FA:
		if(zoneIdx == zone1Idx)
			tagVal.value.val_float = CELL_TYPE_FA_Z1;
		else
			tagVal.value.val_float = CELL_TYPE_FA;
		break;
	case CELL_HECA:
		if(zoneIdx == zone1Idx)
			tagVal.value.val_float = CELL_TYPE_FA_Z1;
		else
			tagVal.value.val_float = CELL_TYPE_HECA;
		break;
	case CELL_COVER_PLUG:
		tagVal.value.val_float = CELL_TYPE_CLUS_VIEW;
		break;
	case CELL_COVER_PLUG_EX:
		tagVal.value.val_float = CELL_TYPE_COVPL_CLJ;
		break;
	case CELL_FFDS_CASK:
		tagVal.value.val_float = CELL_TYPE_FFDS;
		break;
	case -1:
		break;
	}
	if(cellType != -1){
		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	retSt = SetMimicCellSituation(mastType, cellSituation);
	if(retSt != RT_NORMAL)
		return(retSt);

	return(RT_NORMAL);

}
/*------------------------------------------------------------------------------
** Function:		VotedTagWrite
**
** Description:		Write a voted tag set the correspondant _T("I_xxxx") tag before writing
**
** Input			tagName			- mast in use
**					digVal			- tag digital value
**					fltVal			- tag float value
**					type			- tag value type	- DIG_VALUE digital
**														- FLT_VALUE float
**								  
** Return:			RETSTAT		- RT_NORMAL	If tag has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT	VotedTagWrite(TAGNAME tagName, int digVal, float fltVal, int type){
	RETCOND		retCnd;
	TAGNAME		iTagName;
	TAGIDX		cTagIdx;
	TAGIDX		iTagIdx;
	TAGVALEX	iTagVal;
	TAGVALEX	cTagVal;

	retCnd = GetTagIdx(tagName, &cTagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	_stprintf_s(iTagName, _T("I_%s"), tagName);

	retCnd = GetTagIdx(iTagName, &iTagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&iTagIdx, &iTagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	StBit((unsigned short *)(&iTagVal.value.val_di), 15);
	
	retCnd = TagWrite(&iTagIdx, &iTagVal, WRITE_MODE);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	Sleep(vtwSleep);

	retCnd = TagRead(&cTagIdx, &cTagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	switch(type){
	case DIG_VALUE:
		if(digVal == 1)
			StBit((unsigned short *)(&cTagVal.value.val_di), 15);
		else if(digVal == 0)
			ClBit((unsigned short *)(&cTagVal.value.val_di), 15);
		else
			return(RT_FAILED);
		break;
	case FLT_VALUE:
		cTagVal.value.val_float = fltVal;
		break;
	default:
		return(RT_FAILED);
	}

	retCnd = TagWrite(&cTagIdx, &cTagVal, WRITE_MODE);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		VotedTagWriteEx
**
** Description:		Write a voted tag set the correspondant _T("I_xxxx") tag before writing
**
** Input			tagName			- mast in use
**					digVal			- tag digital value
**					fltVal			- tag float value
**					type			- tag value type	- DIG_VALUE digital
**														- FLT_VALUE float
**								  
** Return:			RETSTAT		- RT_NORMAL	If tag has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT	VotedTagWriteEx(TAGNAME tagName, int digVal, float fltVal, int type){
	RETCOND		retCnd;
	TAGNAME		iTagName;
	TAGIDX		cTagIdx;
	TAGIDX		iTagIdx;
	TAGVALEX	iTagVal;
	TAGVALEX	cTagVal;

	retCnd = GetTagIdx(tagName, &cTagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&cTagIdx, &cTagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	switch(type){
	case DIG_VALUE:
		if((digVal == 1) && (GtBit((unsigned short)(cTagVal.value.val_di), 15) == 1))
			return(RT_NORMAL);
		else if((digVal == 0) && (GtBit((unsigned short)(cTagVal.value.val_di), 15) == 0))
			return(RT_NORMAL);
		break;
	case FLT_VALUE:
		if(cTagVal.value.val_float == fltVal)
			return(RT_NORMAL);
		break;
	default:
		return(RT_FAILED);
	}
	
	_stprintf_s(iTagName, _T("I_%s"), tagName);

	retCnd = GetTagIdx(iTagName, &iTagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&iTagIdx, &iTagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	StBit((unsigned short *)(&iTagVal.value.val_di), 15);
	
	retCnd = TagWrite(&iTagIdx, &iTagVal, WRITE_MODE);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	Sleep(vtwSleep);
	
	switch(type){
	case DIG_VALUE:
		if(digVal == 1)
			StBit((unsigned short *)(&cTagVal.value.val_di), 15);
		else if(digVal == 0)
			ClBit((unsigned short *)(&cTagVal.value.val_di), 15);
		else
			return(RT_FAILED);
		break;
	case FLT_VALUE:
		cTagVal.value.val_float = fltVal;
		break;
	default:
		return(RT_FAILED);
	}

	retCnd = TagWrite(&cTagIdx, &cTagVal, WRITE_MODE);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		VotedTagWriteQual
**
** Description:		Write a the quality of a voted tag
**
** Input			tagName			- mast in use
**														- FLT_VALUE float
**					qual			- quality status
**								  
** Return:			RETSTAT		- RT_NORMAL	If tag has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT VotedTagWriteQual(TAGNAME tagName, QUAL qual){
	RETCOND		retCnd;
	TAGNAME		iTagName;
	TAGIDX		cTagIdx;
	TAGIDX		iTagIdx;
	TAGVALEX	iTagVal;
	TAGVALEX	cTagVal;

	retCnd = GetTagIdx(tagName, &cTagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	_stprintf_s(iTagName, _T("I_%s"), tagName);

	retCnd = GetTagIdx(iTagName, &iTagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&iTagIdx, &iTagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	StBit((unsigned short *)(&iTagVal.value.val_di), 15);
	
	retCnd = TagWrite(&iTagIdx, &iTagVal, WRITE_MODE);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	Sleep(SLEEP_BETWEEN_WRITE);

	retCnd = TagRead(&cTagIdx, &cTagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	memcpy(&cTagVal.qual, &qual, sizeof(QUAL));

	retCnd = TagWrite(&cTagIdx, &cTagVal, WRITE_MODE);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetMice
**
** Description:		Write a micro command execution structure in DAFS file F.MICE
**
** Input			mice			- micro command execution structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If mice has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetMice(micro_cmd_exe mice){
	RETCOND			retCnd;
	FILEIDX			fileMice;
	int				rec;
	micro_cmd_exe	temp;

	fileMice.num = F_MICE;

	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileMice, rec, 1, &temp, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(temp.index == 0)
			break;
		if((temp.index == mice.index) && (temp.phase == mice.phase)){
			retCnd = FileWrite(&fileMice, rec, 1, &mice, sizeof(micro_cmd_exe));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		SetMiceStartPos
**
** Description:		Set micro command start position
**
** Input			miceIndex	- micro command execution index
**					px			- start position x coordinate
**					py			- start position y coordinate
**								  
** Return:			RETSTAT		- RT_NORMAL	If mice has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetMiceStartPos(short int miceIndex, float px, float py){
	RETCOND			retCnd;
	FILEIDX			fileMice;
	micro_cmd_exe	mice;
	int				rec;

	fileMice.num = F_MICE;
	
	if((miceIndex < 1) || (miceIndex > N_MAX_MICENR)) 
		return(RT_FAILED);

	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileMice, rec, 1, &mice, sizeof(mice));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(mice.index == miceIndex){
			mice.startPX = px;
			mice.startPY = py;
			retCnd = FileWrite(&fileMice, rec, 1, &mice, sizeof(mice));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			return(RT_NORMAL);
		}
	}
	return(RT_FAILED);

}
/*------------------------------------------------------------------------------
** Function:		InitUTags
**
** Description:		Initialize U_**** tags
**
** Return:			RETSTAT		- RT_NORMAL	If tags hve been initialized
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitUTags(){
	RETCOND		retCnd;
	RETSTAT		retSt;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	int			opMode;

	ZeroMemory(&tagVal, sizeof(TAGVALEX));
	
	tagVal.qual.b.q1imp = 1;

	retSt = GetDynCurrentMode(&opMode);
	if(retSt != RT_NORMAL)
		SetDynCurrentMode(M_AUTOMATIC);
	else
		SetDynCurrentMode(opMode);
	
	ZeroMemory(&tagVal, sizeof(TAGVALEX));
	tagVal.qual.b.q1imp = 1;
	tagVal.value.val_float = 0;
	retCnd = GetTagIdx(TWN_U_CELL_TYPE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = GetTagIdx(TWN_Z1_CONT_TYPE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	ZeroMemory(&tagVal.qual, sizeof(tagVal.qual));
	tagVal.qual.b.q1imp = 1;
	retCnd = GetTagIdx(TWN_U_CONTAINER, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	ZeroMemory(&tagVal, sizeof(TAGVALEX));
	tagVal.qual.b.q1imp = 1;
	tagVal.value.val_float = (float)(0.0);
	retCnd = GetTagIdx(TWN_U_CYCLE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	retSt = SetPhaseSourceDestTags(0);
	if(retSt != RT_NORMAL)
		return(retSt);
	return(RT_NORMAL);
}

//////////////////////////////////////////////////////////////////////////
//
// Bailey Formats Conversions
//
//////////////////////////////////////////////////////////////////////////

// Convert from Realx3 Bailey to Double value
BOOL CvtReal3Double (TCHAR *input,double *double_val)
{
  double fract;
  TCHAR signm;
  int fexp;

  signm = (TCHAR)(input[0] & 1);
  fexp  = (input[0] >> 1);
  fract = (double)(unsigned char)input[2]; fract /= 256.0;
  fract = (fract + (double)(unsigned char)input[1]) / 256.0;

  (*double_val) = ldexp(fract,fexp);
  if(signm) (*double_val) *= -1;

  return TRUE;
}

// Convert from Double value to Realx3 Bailey
BOOL CvtDoubleReal3 (double decimal,TCHAR *sval)
{
  double fract;
  int    exponent;
  long   mantissa;
  TCHAR   signm;

  if(decimal == 0) {
    sval[0] = 0;
    sval[1] = 0;
    sval[2] = 0;
  } else {
    if(decimal < 0.0) {// If neg. make pos for frexp function 
      decimal *= -1.0;
      signm = 1;          
    }
    else
      signm = 0;
  
    fract = frexp(decimal,&exponent);

    exponent *= 2;
    exponent += signm;
    exponent &= 0xFF;

    sval[0] = (TCHAR)exponent;
    mantissa = (long)(fract * ldexp(1.0,16));
    sval[1] = (TCHAR)(mantissa >> 8);
    sval[2] = (TCHAR)(mantissa & 0x00FF);
  }
  
  return TRUE;
}


// Convert from Realx2 Bailey to Double value
BOOL CvtReal2Double (TCHAR *input,double *double_val)
{
  TCHAR signm = ((unsigned char) input[0]) & 0x04;
  int fexp  = (input[0] >> 3) + 7;
  double fract = (double)(unsigned char)input[1]; fract /= 256.0;
  fract = (fract + (double) ((unsigned char)input[0] & 0x03)) / 4;

  (*double_val) = ldexp(fract,fexp);
  if(signm) (*double_val) *= -1;

  return TRUE;
}

// Convert from Double value to Realx2 Bailey
BOOL CvtDoubleReal2 (double decimal, TCHAR *sval)
{
  double fract;
  int    exponent;
  long   mantissa;
  TCHAR   signm;

  // Fix conversion for zero.
  if(decimal == 0) {
    sval[0] = (TCHAR) 0xC8;
    sval[1] = 0;
    return TRUE;
  }

  // If neg. make pos for frexp function 
  if(decimal < 0.0) {
    decimal *= -1.0;
    signm = 1;          
  } else signm = 0;
  
  fract = frexp(decimal, &exponent);

  exponent -= 7;
  exponent <<= 1;
  exponent += signm;
  exponent <<= 2;
  mantissa = (long) (fract * ldexp(1.0,10));
  exponent += (mantissa >> 8) & 3;
  exponent &= 0xFF;
  mantissa &= 0xFF;           

  sval[0] = (TCHAR) (exponent & 0x00FF);
  sval[1] = (TCHAR)(mantissa & 0x00FF);
  
  return TRUE;
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseSourceDestTags
**
** Description:		Set a phase source and dest physical coordinates on the relative tags
**
** Input:			phaseNum	- Phase number (if 0 initialize tags)
**
** Return:			RETSTAT		- RT_NORMAL	If tags hve been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetPhaseSourceDestTags(int phaseNum){
	RETCOND			retCnd;
	RETSTAT			retSt;
	short int		vx, vy;
	t_cell			cell;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	GENIDX			zoneIdx;

	ZeroMemory(&tagVal, sizeof(TAGVALEX));
	tagVal.qual.b.q1imp = 1;
	
	if(phaseNum == 0){
		tagVal.value.val_float = (float)(0.0);
		retCnd = GetTagIdx(TWN_U_SOURCE_X, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		tagVal.value.val_float = (float)(0.0);
		retCnd = GetTagIdx(TWN_U_SOURCE_Y, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		tagVal.value.val_float = (float)(0.0);
		retCnd = GetTagIdx(TWN_U_DEST_X, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		tagVal.value.val_float = (float)(0.0);
		retCnd = GetTagIdx(TWN_U_DEST_Y, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	else{
		retSt = GetPhaseDestVirtCoo(phaseNum, &vx, &vy);
		if(retSt != RT_NORMAL)
			return(retSt);

		retSt = GetZoneVirtPar(vx, vy, &zoneIdx, &cell);
		if(retSt != RT_NORMAL)
			return(retSt);
		
		tagVal.value.val_float = (float)(cell.Phys_X);
		retCnd = GetTagIdx(TWN_U_DEST_X, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		tagVal.value.val_float = (float)(cell.Phys_Y);
		retCnd = GetTagIdx(TWN_U_DEST_Y, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retSt = GetPhaseSourceVirtCoo(phaseNum, &vx, &vy);
		if(retSt != RT_NORMAL)
			return(retSt);

		retSt = GetZoneVirtPar(vx, vy, &zoneIdx, &cell);
		if(retSt != RT_NORMAL)
			return(retSt);
		
		tagVal.value.val_float = (float)(cell.Phys_X);
		retCnd = GetTagIdx(TWN_U_SOURCE_X, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		tagVal.value.val_float = (float)(cell.Phys_Y);
		retCnd = GetTagIdx(TWN_U_SOURCE_Y, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetMimicMastSituation
**
** Description:		Set mast situation on DAFS file for mimic view
**
** Input:			mastType	- mast situation to set (SET_ALL all, INIT_ALL initialize)
**
** Return:			RETSTAT		- RT_NORMAL	If file has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetMimicMastSituation(GENIDX mastType){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileIdx;
	t_cell		dummy;
	OBJTMM		mastSituation;
	int			i;

	fileIdx.num = F_CE30;

	if((mastType < INIT_ALL) && (mastType > MAIN_MAST))
		return(RT_FAILED);

	ZeroMemory(&mastSituation, sizeof(OBJTMM));
	ZeroMemory(&dummy, sizeof(t_cell));

	switch(mastType){
	case MAIN_MAST:
		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL)
			return(retSt);
		for(i = 0; i < N_MAX_NONAM_OBJ; i++)
			dummy.objt_cell.obj[i] = mastSituation.obj[i];
		retCnd = FileWrite(&fileIdx, MM_REC, 1, &dummy, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		break;
	case INIT_ALL:
		retCnd = FileWrite(&fileIdx, MM_REC, 1, &dummy, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		break;
	case SET_ALL:
		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL)
			return(retSt);
		for(i = 0; i < N_MAX_NONAM_OBJ; i++)
			dummy.objt_cell.obj[i] = mastSituation.obj[i];
		retCnd = FileWrite(&fileIdx, MM_REC, 1, &dummy, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	default:
		return(RT_FAILED);
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		MastTrasPos
**
** Description:		Checks if a mast is in transport position and return its position,
**					if mast isn't in transport position returns -1;
**
** Input:			mastType	- mast to check
**
** Return:			RETSTAT		- RT_NORMAL	If position has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT	MastTrasPos(GENIDX mastType, float *transPos){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	if(mastType != MAIN_MAST)
		return(RT_FAILED);

	switch(mastType){
	case MAIN_MAST:
		retCnd = GetTagIdx(TWN_MM_TRANSPOS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short)tagVal.value.val_di, 15) == 0){
			*transPos = -1;
			return(RT_NORMAL);
		}
		else{
			retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			retCnd = TagRead(&tagIdx, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			*transPos = tagVal.value.val_float;
			return(RT_NORMAL);
		}
		break;
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		MastInTouchdown
**
** Description:		Checks if a mast is in touchdown position and return its position,
**					if mast isn't in touchdown position returns -1;
**
** Input:			mastType	- mast to check
**
** Return:			RETSTAT		- RT_NORMAL	If position has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT MastInTouchdown(GENIDX mastType, float *tdPos){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	if(mastType != MAIN_MAST)
		return(RT_FAILED);

	switch(mastType){
	case MAIN_MAST:
		retCnd = GetTagIdx(TWN_MM_TOUCHDOWN, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short)tagVal.value.val_di, 15) == 1){
			*tdPos = -1;
			return(RT_NORMAL);
		}
		else{
			retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			retCnd = TagRead(&tagIdx, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			*tdPos = tagVal.value.val_float;
			return(RT_NORMAL);
		}
		break;
	}
	return(RT_FAILED);

}

/*------------------------------------------------------------------------------
** Function:		GetCurrentUserIdx
**
** Description:		Retrieve the current logged user identifier (F_PSWD record).
**
** Input:			opStation	- Tenore NT station where the user is logged.
**
** Output:			userIdx		- Current logged user identifier
**								  
** Return:			RETSTAT		- RT_NORMAL	If userIdx has been retrieved
**								- RT_FAILED	If errors occurred
*/
API_NT RETSTAT GetCurrentUserIdx(DWORD opStation, int *userIdx){
	RETSTAT			retSt;
	TCHAR			userName[SZUNAM+1];
	

	retSt = GetLoggedUserName(opStation, userName);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetUserIdxFromName(userName, userIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		GetUserIdxFromName
**
** Description:		retrieve a user identifier (F.PSWD number) from its name
**
** Input			userName	- user name
**
** Output			userIdx		- user identifier
**								  
** Return:			RETSTAT		- RT_NORMAL	If userIdx has been retrieved
**								- RT_FAILED	If errors occurred
*/
API_NT RETSTAT GetUserIdxFromName(TCHAR userName[SZUNAM+1], int *userIdx){
	RETCOND			retCnd;
	t_pswd_record	usrRec;
	FILEIDX			fileIdx;
	int				rec;

	fileIdx.num = F_PSWD;

	for(rec = 1; rec <= TNT_MAX_USER; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &usrRec, sizeof(t_pswd_record));
		if(retCnd = R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(userName, usrRec.ipwopn)){
			*userIdx = rec;
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetUserNameFromIdx
**
** Description:		Retrieve a user's name from its identifier (F.PSWD record)
**
** Input			userIdx		- user identifier
**
** Output			userName	- user name
**								  
** Return:			RETSTAT		- RT_NORMAL	If user name has been retrieved
**								- RT_FAILED	If errors occurred
*/
API_NT RETSTAT GetUserNameFromIdx(int userIdx, TCHAR userName[SZUNAM+1]){
	RETCOND			retCnd;
	t_pswd_record	usrRec;
	FILEIDX			fileIdx;

	fileIdx.num = F_PSWD;
	
	retCnd = FileRead(&fileIdx, userIdx, 1, &usrRec, sizeof(t_pswd_record));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	_stprintf_s(userName,sizeof(userName), _T("%s"), usrRec.ipwopn);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetMimicMastAndCellSituation
**
** Description:		Set mimic mast and cell situation. Write U_CELL_TYPE too.
**
** Return:			RETSTAT		- RT_NORMAL	If info have been set
**								- RT_FAILED	If errors occurred
/*----------------------------------------------------------------------------*/
RETSTAT SetMimicMastAndCellSituation(void){
	RETSTAT		retSt;
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	OBJTCELL	cellSituation;
	int			cellType;
	float		px, py;
	short int	vx, vy;
	GENIDX		mastMounted;
	GENIDX		zone1Idx;
	int			i;
	GENIDX		zoneIdx;
	bool		outOfZone;

	retSt = GetMastMounted(&mastMounted);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = MAIN_MAST; i <= DMP_MAST; i++){
		if(i == mastMounted){
			outOfZone = false;
			retSt = GetMastPosInfiSC(i, &px, &py, &zoneIdx);
			if(retSt == RT_FAILED)
				return(retSt);
			else if(retSt == RT_INVZONE)
				outOfZone = true;
			if(zoneIdx > 0){
				ZeroMemory(&cellSituation, sizeof(OBJTCELL));
				cellType = -1;
				if(!outOfZone){
					retSt = GetZoneIdx(ZONE_IO, &zone1Idx);
					if(retSt != RT_NORMAL)
						return(retSt);

					retSt = GetVirtCoordFromZoneAndPhysCoord(px, py, zoneIdx, &vx, &vy);
					if((retSt == RT_NORMAL) && (zoneIdx > 0)){
						retSt = GetCellSituation(vx, vy, &cellSituation);
						if(retSt != RT_NORMAL)
							return(retSt);

						retSt = GetCellType(vx, vy, &cellType);
						if(retSt != RT_NORMAL)
							return(retSt);
					}
					else{
						ZeroMemory(&cellSituation, sizeof(OBJTCELL));
						cellType = CELL_NULL;
					
					}
				}
				retSt = SetMimicCellSituation(i, cellSituation);
				if(retSt != RT_NORMAL)
					return(retSt);

				retCnd = GetTagIdx(TWN_U_CELL_TYPE, &tagIdx);
				if(retCnd != R_NORMAL)
					return(RT_FAILED);

				ZeroMemory(&tagVal, sizeof(TAGVALEX));
				tagVal.qual.b.q1imp = 1;
				switch(cellType){
				case CELL_NULL:
					tagVal.value.val_float = CELL_TYPE_NULL;
					break;
				case CELL_FA:
					if(zoneIdx == zone1Idx)
						tagVal.value.val_float = CELL_TYPE_FA_Z1;
					else
						tagVal.value.val_float = CELL_TYPE_FA;
					break;
				case CELL_HECA:
					if(zoneIdx == zone1Idx)
						tagVal.value.val_float = CELL_TYPE_FA_Z1;
					else
						tagVal.value.val_float = CELL_TYPE_HECA;
					break;
				case CELL_COVER_PLUG:
					tagVal.value.val_float = CELL_TYPE_CLUS_VIEW;
					break;
				case CELL_COVER_PLUG_EX:
					tagVal.value.val_float = CELL_TYPE_COVPL_CLJ;
					break;
				case CELL_FFDS_CASK:
					tagVal.value.val_float = CELL_TYPE_FFDS;
					break;
				case -1:
					break;
				}
				if(cellType != -1){
					retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
					if(retCnd != R_NORMAL)
						return(RT_FAILED);
				}
			}
		}

		if(i == MAIN_MAST){
			retSt = SetMimicMastSituation(i);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMastMounted
**
** Description:		Retrieve the currently mounted mast
**
** Return:			RETSTAT		- RT_NORMAL	If mounted mast has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMastMounted(GENIDX *mastType){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	retCnd = GetTagIdx(TWN_FALVL_MOUNT, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short)tagVal.value.val_di, 15) == 1){
		*mastType = FALC_MAST;
		return(RT_NORMAL);
	}
	else{
		retCnd = GetTagIdx(TWN_DIMP_MOUNT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(GtBit((short)tagVal.value.val_di, 15) == 1){
			*mastType = DMP_MAST;
			return(RT_NORMAL);
		}
		else{
			retCnd = GetTagIdx(TWN_MM_MOUNT, &tagIdx);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);

			retCnd = TagRead(&tagIdx, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);

			if(GtBit((short)tagVal.value.val_di, 15) == 1){
				*mastType = MAIN_MAST;
				return(RT_NORMAL);
			}
			else
				*mastType = -1;


		}
		return(RT_NORMAL);
	}
		
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMastPosInfiSC
**
** Description:		Retrieve a mast position from Infi90, used in SafeChecks
**
** Input			mastType	- mast type used
**
** Output			px			- mast physical X coordinate
**					py			- mast physical Y coordinate
**					zoneIdx		- zone idx containing mast
**								  
** Return:			RETSTAT		- RT_NORMAL	If position has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMastPosInfiSC(GENIDX mastType, float *px, float *py, GENIDX *zoneIdx){
	RETCOND		retCnd;
	RETSTAT		retSt;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	float		bridgeX, trolleyY, cantiY;
	float		x, y;
	float		x_off;
	float		y_off;
	t_zone		zoneIO;
	t_zone		zoneReact;
	t_zone		zoneFFDS;
	t_zone		zoneMain;
	t_zone		zoneZ212;
	GENIDX		IOZoneIdx;
	GENIDX		reactZoneIdx;
	GENIDX		FFDSZoneIdx;
	GENIDX		mainZoneIdx;
	GENIDX		Z212Idx;

	bridgeX = 0.0;
	trolleyY = 0.0;
	cantiY = 0.0;
	
	retCnd = GetTagIdx(TWN_BRIDGE_POS, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	bridgeX = tagVal.value.val_float;
	
	retCnd = GetTagIdx(TWN_TROLLEY_POS,&tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	trolleyY = tagVal.value.val_float;
	
	
	switch(mastType){
	case MAIN_MAST:
		x = bridgeX;
		y = trolleyY;
		break;
	case FALC_MAST:
	case DMP_MAST:
		GetFALVOffset(&x_off, &y_off);
		x = bridgeX + (float)(x_off);
		y = trolleyY + (float)(y_off);
		break;
	case TV_MAST:
		x = bridgeX;
		y = trolleyY;
		break;
	}
	
	*px = x;
	*py = y;

	retSt = GetZoneIdx(ZONE_IO, &IOZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(IOZoneIdx, &zoneIO);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_REACTOR, &reactZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(reactZoneIdx, &zoneReact);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_FFDS, &FFDSZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(FFDSZoneIdx, &zoneFFDS);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_MAIN, &mainZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(mainZoneIdx, &zoneMain);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZoneIdx(ZONE_FA_02, &Z212Idx);
	if(retSt != RT_NORMAL)
		return(retSt);
	retSt = GetZone(mainZoneIdx, &zoneZ212);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(x >= zoneReact.zone_coord.L_H_CooX - (float)(TOLL_MM)){
		*zoneIdx = reactZoneIdx;
		return(RT_NORMAL);
	}
	else if((x > zoneMain.zone_coord.R_L_CooX + (float)(TOLL_MM)) && (x < zoneReact.zone_coord.L_H_CooX - (float)(TOLL_MM))){
		*zoneIdx = ZONE_C23_IDX;
		return(RT_NORMAL);

	}
	
	if((x > zoneIO.zone_coord.R_L_CooX + (float)(TOLL_MM)) && (x < zoneZ212.zone_coord.L_H_CooX - (float)(TOLL_MM)) && (y > zoneFFDS.zone_coord.L_H_CooY + (float)(TOLL_MM))){
		*zoneIdx = ZONE_C12_IDX;
		return(RT_NORMAL);
	}
	else if((x <= zoneIO.zone_coord.R_L_CooX + (float)(TOLL_MM)) && (y >= zoneIO.zone_coord.R_L_CooY + (float)(TOLL_MM))){
		*zoneIdx = IOZoneIdx;
		return(RT_NORMAL);
	}

	retSt = GetZoneIdxPhisCoo(x, y, zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	else
		return(RT_NORMAL);

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneIdxPhisCooSC
**
** Description:		Retrieve a zone idx from physical coordinates, used in SafeChecks
**
** Input			Coo_X		- physical X coordinate
**					Coo_Y		- physical Y coordinate
**
** Output			zoneIdx		- zone idx containing input coordinates
**					
**								  
** Return:			RETSTAT		- RT_NORMAL	If position has been retrieved
**								- RT_INVZONE If coordinates aren't in any zone.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetZoneIdxPhisCooSC(float Coo_X, float Coo_Y, GENIDX *zoneIdx){
	RETCOND		stat;
	RETSTAT		retSt;
	t_zone		zone;
	int			i;
	FILEIDX		file;
	GENIDX		mainPoolIdx;

	*zoneIdx = (GENIDX)0;

	file.num = F_ZONE;

	retSt = GetZoneIdx(ZONE_MAIN, &mainPoolIdx);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	for(i = 0; i < N_MAX_ZONE; i++){
	  
		if(i == mainPoolIdx - 1)
			continue;

		stat = FileRead(&file , (i+1), 1, &zone, sizeof(t_zone) );
		if((zone.zone_coord.L_H_CooX == 0) &&
		   (zone.zone_coord.L_H_CooY == 0) &&
           (zone.zone_coord.R_L_CooX == 0) &&
           (zone.zone_coord.R_L_CooY == 0))
			break;
		
		if((Coo_X >= zone.zone_coord.L_H_CooX - (float)(TOLL_MM)) &&
		   (Coo_Y <= zone.zone_coord.L_H_CooY + (float)(TOLL_MM)) &&
           (Coo_X <= zone.zone_coord.R_L_CooX + (float)(TOLL_MM)) &&
           (Coo_Y >= zone.zone_coord.R_L_CooY - (float)(TOLL_MM))){
			*zoneIdx = (GENIDX)(i+1);
			return (RT_NORMAL);
		}
	}
	return(RT_INVZONE);
}

/*------------------------------------------------------------------------------
** Function:		GetVirtCoordFromZoneAndPhysCoord
**
** Description:		Retrieve a cell vitual coordinates from physical coordinates and zone 
**					Idx. Used in SafeChecks, is faster than GetZoneNearCell, check only
**					in +/- TOLL_MM range around the cells.
**
** Input			px			- physical X coordinate
**					py			- physical Y coordinate
**					zoneIdx		- zone idx containing input coordinates
**
** Output			vx			- cell virtual X coordinate
**					vy			- cell virtual Y coordinate
**					
**								  
** Return:			RETSTAT		- RT_NORMAL	If virtual coordinates have been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetVirtCoordFromZoneAndPhysCoord(float px, float py, GENIDX zoneIdx, short int *vx, short int *vy){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_cell		cell;
	int			rec;

	fileIdx.num = F_CE01 + zoneIdx - 1;

	for(rec = 1; rec < N_MAX_CELL; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			break;
		if(cell.Virt_X != 0){
			if(((px >= cell.Phys_X - (float)(TOLL_MM_CELLS)) && (px <= cell.Phys_X + (float)(TOLL_MM_CELLS))) && ((py >= cell.Phys_Y - (float)(TOLL_MM_CELLS)) && (py <= cell.Phys_Y + (float)(TOLL_MM_CELLS)))){
				*vx = cell.Virt_X;
				*vy = cell.Virt_Y;
				return(RT_NORMAL);
			}
		}
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckInsertFeasibility
**
** Description:		Checks if objects on a mast can be inserted in a cell
**
** Input			mastType	- mast carrying objects
**					vx			- cell virtual X coordinate
**					vy			- cell virtual Y coordinate
**								  
** Return:			RETSTAT		- RT_NORMAL	If objects can be nserted in the cell
**								- RT_FAILED	If errors occurred
*/
RETSTAT CheckInsertFeasibility(GENIDX mastType, short int vx, short int vy){
	RETSTAT		retSt;
	OBJTMM		mastSituation;
	OBJTCELL	cellSituation;
	int			i;
	int			cellType;
	bool		noObjOnMast;

	noObjOnMast = true;

	if(mastType == MAIN_MAST){
		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL)
			return(retSt);
		retSt = GetCellSituation(vx, vy, &cellSituation);
		if(retSt != RT_NORMAL)
			return(retSt);
		retSt = GetCellType(vx, vy, &cellType);
		if(retSt != RT_NORMAL)
			return(retSt);
		for(i = 0; i < N_MAX_NONAM_OBJ; i++){
			if((mastSituation.obj[i] != 0) && (cellSituation.obj[i] != 0))
				return(RT_FAILED);
		}

		if(mastSituation.obj[OBJT_N_HECA] != 0){
			noObjOnMast = false;
			if(cellType == CELL_HECA)
				return(RT_NORMAL);
			else 
				return(RT_FAILED);
		}
		else if(mastSituation.obj[OBJT_N_FA] != 0){
			noObjOnMast = false;
			if((cellType == CELL_FA) && (cellSituation.obj[OBJT_N_CLUS_CAS] != 0) && (cellSituation.obj[OBJT_N_CLUS_FRM] != 0))
				return(RT_NORMAL);
			else if((cellType == CELL_HECA) && (cellSituation.obj[OBJT_N_HECA] != 0) && (cellSituation.obj[OBJT_N_COVER] == 0))
				return(RT_NORMAL);
			else if((cellType == CELL_FFDS_CASK) && (cellSituation.obj[OBJT_N_FFDS_COV] == 0))
				return(RT_NORMAL);
			else 
				return(RT_FAILED);
		}
		else if(mastSituation.obj[OBJT_N_CLUS] != 0){
			noObjOnMast = false;
			if((cellType == CELL_FA) && ((cellSituation.obj[OBJT_N_FA] != 0) || (cellSituation.obj[OBJT_N_CLUS_FRM] != 0)))
				return(RT_NORMAL);
			else
				return(RT_FAILED);
		}
		else if(mastSituation.obj[OBJT_N_COVER] != 0){
			noObjOnMast = false;
			if((cellType == CELL_HECA) && (cellSituation.obj[OBJT_N_HECA] != 0))
				return(RT_NORMAL);
			else if(((cellType == CELL_COVER_PLUG) || (cellType == CELL_COVER_PLUG_EX))&& (cellSituation.obj[OBJT_N_FFDS_COV] == 0))
				return(RT_NORMAL);
			else 
				return(RT_FAILED);
		}
		else if(mastSituation.obj[OBJT_N_FFDS_COV] != 0){
			noObjOnMast = false;
			if(cellType == CELL_FFDS_CASK)
				return(RT_NORMAL);
			else if(((cellType == CELL_COVER_PLUG) || (cellType == CELL_COVER_PLUG_EX)) && (cellSituation.obj[OBJT_N_COVER] == 0))
				return(RT_NORMAL);
			else 
				return(RT_FAILED);
		}
		else if(mastSituation.obj[OBJT_N_CLUS_CAS] != 0){
			noObjOnMast = false;
			if(cellType == CELL_FA){
				if(cellSituation.obj[OBJT_N_CLUS] != 0)
					return(RT_NORMAL);
			}
			else if((cellType == CELL_COVER_PLUG_EX) && (cellSituation.obj[OBJT_N_COVER] == 0) && (cellSituation.obj[OBJT_N_FFDS_COV] == 0))
					return(RT_NORMAL);
			else 
				return(RT_FAILED);
		}
		else if(mastSituation.obj[OBJT_N_CLUS_FRM] != 0)
			return(RT_FAILED);
		if(noObjOnMast){
			if((cellSituation.obj[OBJT_N_FA] != 0) || ((cellSituation.obj[OBJT_N_HECA] != 0) && (cellSituation.obj[OBJT_N_COVER] != 0)) || (cellSituation.obj[OBJT_N_CLUS_CAS] != 0) || (cellSituation.obj[OBJT_N_CLUS_FRM] != 0)  || (cellSituation.obj[OBJT_N_FFDS_COV] != 0))
				return(RT_NORMAL);
			else
				return(RT_FAILED);
		}
	}
	else if(mastType == FALC_MAST){
		retSt = GetCellSituation(vx, vy, &cellSituation);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(cellSituation.obj[OBJT_N_FA] != 0)
			return(RT_FAILED);
		else
			return(RT_NORMAL);
	}
	else{
		retSt = GetCellSituation(vx, vy, &cellSituation);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(cellSituation.obj[OBJT_N_FA] == 0)
			return(RT_FAILED);
		else
			return(RT_NORMAL);
	
	}
	
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMovingMast
**
** Description:		Retrieve if a FA gripper is moving
**
** Input			tagMmFAGRIdx	- MM FA gripper tag idx
**					tagStartIdx		- Start Tag Idx
**
** Output			movingMast		- mast in movement
**					direction		- movement direction	MOVING_UPWARD
**															MOVING_DOWNWARD
**									
**								  
** Return:			RETSTAT			- RT_NORMAL	If moving FA gripper has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetMovingMast(TAGIDX tagStartIdx, TAGIDX tagMmFAGRIdx, GENIDX *movingMast, int *direction){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	TAGVALEX	tagVal_2;
	
	*direction = 0;
	
	retCnd = TagRead(&tagStartIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 0){
		*movingMast = -1;	
		return(RT_NORMAL);
	}

	retCnd = TagRead(&tagMmFAGRIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
			
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = GetTagIdx(TWN_FAGR_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
			
		retCnd = TagRead(&tagIdx, &tagVal_2);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(tagVal_2.value.val_float > (tagVal.value.val_float + (float)(TOLL_MM)))
			*direction = MOVING_DOWNWARD;
		else
			*direction = MOVING_UPWARD;
			
		*movingMast = MAIN_MAST;	
		return(RT_NORMAL);
	}
	*movingMast = -1;	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetMimicTCStatus
**
** Description:		Set technological cycle status on a tags for mimics
**
** Input:			status			- 0 no cycles in execution
**									- 1 OK
**									- 2 Paused
**									- 3 Alarm
**
** Return:			RETSTAT			- RT_NORMAL	If status has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetMimicTCStatus(int status){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	if((status < 0) || (status > 3))
		return(RT_FAILED);
	
	retCnd = GetTagIdx(TWN_U_CYCLE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	tagVal.value.val_float = (float)(status);

	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseOperator
**
** Description:		Set operator in phase structure
**
** Input:			phasNum			- phase number
**					opName			- name of the operator who executes cycle
**
** Return:			RETSTAT			- RT_NORMAL	If opName has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetPhaseOperator(int phasNum, TCHAR opName[SZUNAM+1]){
	RETSTAT		retSt;
	GENIDX		opIdx;
	phas_struc	phas;

	retSt = GetPhase(phasNum, &phas);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	retSt = GetUserIdxFromName(opName, &opIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	phas.startCondUserIdx = opIdx;

	retSt = SetPhase(phas);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseOperator
**
** Description:		Retrieve the name of the operator who executed a phase
**
** Input:			phasNum			- phase number
**									
** Output:			opName			- name of the operator who executes cycle
**
** Return:			RETSTAT			- RT_NORMAL	If opName has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseOperator(int phasNum, TCHAR opName[SZUNAM+1]){
	RETSTAT		retSt;
	phas_struc	phas;

	retSt = GetPhase(phasNum, &phas);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	retSt = GetUserNameFromIdx(phas.startCondUserIdx, opName);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseHECACoord
**
** Description:		Retrieve the selected coordinates for HECA plug storage
**
** Input:			phasNum			- phase number
**									
** Output:			hecaVx			- HECA plug seat x virtual coordinate
**					hecaVy			- HECA plug seat y virtual coordinate
**
** Return:			RETSTAT			- RT_NORMAL	If coordinates have been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseHECACoord(int phasNum, short int *hecaVx, short int *hecaVy){
	RETSTAT		retSt;
	phas_struc	phas;

	retSt = GetPhase(phasNum, &phas);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	*hecaVx = phas.HECA_INT_VX;
	*hecaVy = phas.HECA_INT_VY;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetPhaseFFDSCoord
**
** Description:		Retrieve the selected coordinates for FFDS plug storage
**
** Input:			phasNum			- phase number
**									
** Output:			ffdsVx			- FFDS plug seat x virtual coordinate
**					ffdsVy			- FFDS plug seat y virtual coordinate
**
** Return:			RETSTAT			- RT_NORMAL	If coordinates have been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetPhaseFFDSCoord(int phasNum, short int *ffdsVx, short int *ffdsVy){
	RETSTAT		retSt;
	phas_struc	phas;

	retSt = GetPhase(phasNum, &phas);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	*ffdsVx = phas.FFDS_INT_VX;
	*ffdsVy = phas.FFDS_INT_VY;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		AddTechCycCond
**
** Description:		Adds a start condition in a technological cycle structure.
**
** Input:			tc				- technological cycle structure
**					condIdx			- identifier of the condition to add
**									
** Return:			RETSTAT			- RT_NORMAL	If condition has been added
**									- RT_FAILED	If errors occurred
*/
RETSTAT AddTechCycCond(t_teccyc *tc, GENIDX condIdx){
	if(tc->numStartConditions < N_COND_PER_TC){
		tc->startCondIdx[tc->numStartConditions] = condIdx;
		tc->numStartConditions++;
		return(RT_NORMAL);
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetTechCycCondEx
**
** Description:		Retrieve a Tech. Cycle condition structure
**
** Input			tc			- Tech. Cycle structure
**					numCond		- condition number (zero based)
** Output			cond		- condition structure
**								  
** Return:			RETSTAT		- RT_NORMAL	If condition has been rretrieved.
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTechCycCondEx(t_teccyc tc, int numCond, tcStartCond *cond){
	RETCOND		retCnd;
	GENIDX		condIdx;
	FILEIDX		fileCond;
	int			rec;

	fileCond.num = F_COND;

	condIdx = tc.startCondIdx[numCond];
	
	for(rec = 1; rec <= N_MAX_START_COND; rec++){
		retCnd = FileRead(&fileCond, rec, 1, cond, sizeof(tcStartCond));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(cond->idx == condIdx)
			return(RT_NORMAL);
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		DecodeFunctionCodeEx
**
** Description:		Decode the result of a Infi90 block read
**
** Input			blkz		- TCHAR string read from block
**					
** Output			m_spcdat	- output data buffer
**								  
** Return:			RETSTAT		- RT_NORMAL	If input has been decoded
**								- RT_FAILED	If errors occurred
*/
RETSTAT DecodeFunctionCodeEx(BYTE *blkz, t_spcdat *m_spcdat){
	BYTE		*blkhdr,*blkdat;
	int			i, j, k;
	DOUBLE		dValue;
	int			iCount, iDataType, iFunctionType;
	BOOL		bTuneFlag;
	int			m_numspc;
	int			m_iFunctionCode;
	int nmspec = blkz[0];
	
	
	ZeroMemory(m_spcdat, sizeof(t_spcdat));

	int ifcloc = nmspec*2 + 2;
	m_iFunctionCode  = blkz[ifcloc-1];
	m_spcdat->functionCode = m_iFunctionCode;
  
	// Decode the Function Code.
	blkhdr =  blkz;
	blkdat = &blkz[ifcloc];
    
	// Get # of spec records and total # of specs
	int bhptr = 0;
	int nmsrec = blkhdr[bhptr];
	bhptr++;
	int tbhptr = bhptr;
	for(m_numspc = 0, i =0; i < nmsrec; i++) {
		m_numspc += blkhdr[tbhptr];
		tbhptr += 2;
	}
  
	//  do conversion & store data in local table
	int blkptr = 0;
	for (i = 0, k =0; i< nmsrec; i++) {
        // Spec count
		iCount = blkhdr[bhptr++];

		// Data type
		iDataType = blkhdr[bhptr] % 16;

		// Tune flag
		bTuneFlag = FALSE;
		if (blkhdr[bhptr] >= 128) bTuneFlag = TRUE;

		// Par. function type
		int temp = blkhdr[bhptr] / 16;
		iFunctionType = temp % 8;
    
		bhptr++;
    
		// Get block data depending on real or integer type
    
		for(j = 0; j < iCount; j++, k++){
			switch(iDataType){
			case 1:  //real 2
				CvtReal2Double ((TCHAR*) &blkdat[blkptr], &dValue);
				m_spcdat->rValue = (float) dValue;
				blkptr += 2;
				break;
			case 2: // real 3
				CvtReal3Double ((TCHAR*) &blkdat[blkptr], &dValue);
				m_spcdat->rValue = (float) dValue;
				blkptr += 3;
				break;
			case 3:  //boolean or integer 1
			case 4:
				m_spcdat->iValue = blkdat[blkptr];
				blkptr++;
				break;
			case 5:  // integer2
				memcpy (&m_spcdat[k].iValue, &blkdat[blkptr], 2);
				_swab( (char *)&m_spcdat->iValue, 
					(char *)&m_spcdat->iValue, 2 );
				blkptr += 2;
			}
			m_spcdat->datatype = iDataType;
			m_spcdat->tuneflag = bTuneFlag;
		}
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		RecodeFunctionCodeParamsEx
**
** Description:		Encode the result of a Infi90 block read
**
** Input			blkz		- TCHAR string read from block
**					
** Output			m_spcdat	- output data buffer
**								  
** Return:			RETSTAT		- RT_NORMAL	If input has been decoded
**								- RT_FAILED	If errors occurred
*/
int RecodeFunctionCodeParamsEx(BYTE *blkz, BYTE *blkdat, t_spcdat my_buf){
	BYTE		*blkhdr;
	int			i, j, k;
	int			blkptr = 0;
	DOUBLE		dValue;
	int			iCount, iDataType, iFunctionType;
	BOOL		bTuneFlag;
	int			m_numspc;

	int nmspec = blkz[0];
	int ifcloc = nmspec*2 + 2;
  
	// Decode the Function Code.
	blkhdr =  blkz;
    
	// Get # of spec records and total # of specs
	int bhptr = 0;
	int nmsrec = blkhdr[bhptr];
	bhptr++;
	int tbhptr = bhptr;
	for(m_numspc = 0, i =0; i < nmsrec; i++){
		m_numspc += blkhdr[tbhptr];
		tbhptr += 2;
	}
  
	//  do conversion & store data from local table
	for(i = 0, k =0; i< nmsrec; i++){
        // Spec count
		iCount = blkhdr[bhptr++];

		// Data type
		iDataType = blkhdr[bhptr] % 16;

		// Tune flag
		bTuneFlag = FALSE;
		if (blkhdr[bhptr] >= 128) bTuneFlag = TRUE;

		// Par. function type
		int temp = blkhdr[bhptr] / 16;
		iFunctionType = temp % 8;
		
		bhptr++;
    
		// Get block data depending on real or integer type
    
		for(j=0; j < iCount; j++, k++){
			switch(iDataType){
			case 1:  //real 2
				dValue = my_buf.rValue;
				CvtDoubleReal2 ( dValue, (TCHAR*) &blkdat[blkptr] );
				blkptr += 2;
				break;
			case 2: // real 3
				dValue = my_buf.rValue;
				CvtDoubleReal3 ( dValue, (TCHAR*) &blkdat[blkptr] );
				blkptr += 3;
				break;
			case 3:  // boolean
				blkdat[blkptr] = my_buf.iValue != 0 ? '\1' : '\0';
				blkptr++;
				break;
			case 4:  // integer 1
				blkdat[blkptr] = (char) my_buf.iValue;
				blkptr++;
				break;
			case 5:  // integer2
				memcpy (&blkdat[blkptr], &my_buf.iValue, 2);
				_swab( (char *)&blkdat[blkptr], (char *)&blkdat[blkptr], 2 );
				blkptr += 2;
			}
		}
	}
	return blkptr;
}

/*------------------------------------------------------------------------------
** Function:		SetInfiBlockVal
**
** Description:		Set a value on an Infi90 Block and on DAFS file
**
** Input			pcu			- Block address pcu
**					block		- Block address number
**					val			- Value to write on block
**					
** Return:			RETSTAT		- RT_NORMAL	If block has been written
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetInfiBlockVal(int block, int pcu, float val){
	RETSTAT				retSt;
	RETCOND				retCnd;
	HRESULT				hr;
	READ_BLOCK_DATA		replBuf;
	TUNE_BLOCK_PARAM	tbParam;
	t_spcdat			m_buf;
	INFI90ADR			infiAddr;
	int					recNum;
	t_infiBlock			dummyBlock;
	
	if(pcu == 0){
		retSt = GetInfiBlockRecFromInfiAddr(block, &recNum);
		if(retSt != RT_NORMAL)
			return(RT_FAILED);
		retSt = GetInfiBlock(recNum, &dummyBlock);
		if(retSt != RT_NORMAL)
			return(RT_FAILED);
		dummyBlock.value = val;
		GetApmsTimeEx(&dummyBlock.lastMod);
		retSt = SetInfiBlock(dummyBlock);
		if(retSt != RT_NORMAL)
			return(retSt);
	}

	retCnd = ApmsIciSrvConnect();
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockRecFromInfiAddr(block, &recNum);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	retSt = GetInfiBlock(recNum, &dummyBlock);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	if((pcu != dummyBlock.pcu[PCU_CH_A]) && (pcu != dummyBlock.pcu[PCU_CH_B]))
		return(RT_FAILED);

	infiAddr.s_loop = dummyBlock.loop;
    infiAddr.s_node = pcu;
    infiAddr.s_module = dummyBlock.module;
    infiAddr.s_block = dummyBlock.block;

    ZeroMemory(&replBuf, sizeof(READ_BLOCK_DATA));
	ZeroMemory(&m_buf, sizeof(t_spcdat));

    hr = ReadBlock(dummyBlock.ici, &infiAddr, &replBuf);
	if(!FAILED(hr)){
		retSt = DecodeFunctionCodeEx ((BYTE*) &replBuf.c_block_data, &m_buf);
		if(retSt != RT_NORMAL){
			retCnd = ApmsIciSrvDisconnect();
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
		}
	}
    else{
		retCnd = ApmsIciSrvDisconnect();
		return(RT_FAILED);		
	}

	m_buf.rValue = val;

	ZeroMemory( &tbParam, sizeof(TUNE_BLOCK_PARAM));
    tbParam.stp_infi90_address = &infiAddr;
    tbParam.s_function_code = m_buf.functionCode;
	tbParam.c_buffer_len = RecodeFunctionCodeParamsEx((BYTE*)replBuf.c_block_data, (BYTE*)&tbParam.c_buffer, m_buf);
	retCnd = TuneBlock(dummyBlock.ici, &tbParam);
	if(retCnd != R_NORMAL){
		retCnd = ApmsIciSrvDisconnect();
		return(RT_FAILED);
	}
	
	dummyBlock.value = val;
	GetApmsTimeEx(&dummyBlock.lastMod);
	retSt = SetInfiBlock(dummyBlock);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = ApmsIciSrvDisconnect();
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetInfiBlockVal
**
** Description:		Get a value of an Infi90 Block
**
** Input			pcu			- Block address pcu
**					block		- Block address number
**
** Output			val			- Value to write on block
**					
** Return:			RETSTAT		- RT_NORMAL	If block has been read
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetInfiBlockVal(int block, int pcu, float *val){
	RETSTAT				retSt;
	RETCOND				retCnd;
	HRESULT				hr;
	READ_BLOCK_DATA		replBuf;
	FILEIDX				fileIdx;
	t_infiBlock			dummyBlock;
	t_spcdat			m_buf;
	INFI90ADR			infiAddr;
	int					blockRec;
	
	fileIdx.num = F_INBL;

	if(pcu == 0){
		retSt = GetInfiBlockRecFromInfiAddr(block, &blockRec);
		if(retSt != RT_NORMAL)
			return(RT_FAILED);
		
		retCnd = FileRead(&fileIdx, blockRec, 1, &dummyBlock, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*val = dummyBlock.value;
		
		return(RT_NORMAL);
	}

	retCnd = ApmsIciSrvConnect();
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockRecFromInfiAddr(block, &blockRec);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
		
	retCnd = FileRead(&fileIdx, blockRec, 1, &dummyBlock, sizeof(t_infiBlock));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if((pcu != dummyBlock.pcu[PCU_CH_A]) && (pcu != dummyBlock.pcu[PCU_CH_B]))
		return(RT_FAILED);

	infiAddr.s_loop = dummyBlock.loop;
    infiAddr.s_node = pcu;
    infiAddr.s_module = dummyBlock.module;
    infiAddr.s_block = block;

    ZeroMemory(&replBuf, sizeof(READ_BLOCK_DATA));
	ZeroMemory(&m_buf, sizeof(t_spcdat));

    hr = ReadBlock(dummyBlock.ici, &infiAddr, &replBuf);
	if(!FAILED(hr)){
		retSt = DecodeFunctionCodeEx ((BYTE*) &replBuf.c_block_data, &m_buf);
		if(retSt != RT_NORMAL){
			retCnd = ApmsIciSrvDisconnect();
			return(retSt);
		}
	}
    else{
		retSt = GetInfiBlockRecFromInfiAddr(block, &blockRec);
		if(retSt != RT_NORMAL)
			return(RT_FAILED);
		
		retCnd = FileRead(&fileIdx, blockRec, 1, &dummyBlock, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*val = dummyBlock.value;
		
		return(RT_NORMAL);
	}
	/*
	if(m_buf.rValue == 0.0){
		retSt = GetInfiBlockRecFromInfiAddr(ici, loop, pcu, module, block, &blockRec);
		if(retSt != RT_NORMAL)
			return(RT_FAILED);
		
		retCnd = FileRead(&fileIdx, blockRec, 1, &dummyBlock, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*val = dummyBlock.value;
		
		return(RT_NORMAL);
	}
	*/
	*val = m_buf.rValue;

	retCnd = ApmsIciSrvDisconnect();
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetInfiBlockValEx
**
** Description:		Get a value of an Infi90 Block
**
** Input			pcu			- Block address pcu
**					block		- Block address number
**					flag		- TUNE_FROM_INFI
**								  TUNE_FROM_DAFS
**
** Output			val			- Block's value
**					
** Return:			RETSTAT		- RT_NORMAL	If block has been read
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetInfiBlockValEx(int block, int pcu, int flag, float *val){
	RETSTAT				retSt;
	RETCOND				retCnd;
	HRESULT				hr;
	READ_BLOCK_DATA		replBuf;
	t_spcdat			m_buf;
	t_infiBlock			infiBlock;
	INFI90ADR			infiAddr;
	FILEIDX				fileIdx;
	int					rec;
	
	if(flag == TUNE_FROM_DAFS){
		retSt = GetInfiBlockRecFromInfiAddr(block, &rec);
		if(retSt != RT_NORMAL)
			return(retSt);
		fileIdx.num = F_INBL;
		retCnd = FileRead(&fileIdx, rec, 1, &infiBlock, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		*val = infiBlock.value;
		return(RT_NORMAL);
	}

	retCnd = ApmsIciSrvConnect();
	if(retCnd != R_NORMAL){
		if(flag == TUNE_FROM_INFI)
			return(RT_FAILED);
		else{
			retSt = GetInfiBlockRecFromInfiAddr(block, &rec);
			if(retSt != RT_NORMAL)
				return(retSt);
			fileIdx.num = F_INBL;
			retCnd = FileRead(&fileIdx, rec, 1, &infiBlock, sizeof(t_infiBlock));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			*val = infiBlock.value;
			return(RT_NORMAL);
		}
	}

	retSt = GetInfiBlockRecFromInfiAddr(block, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);
	fileIdx.num = F_INBL;
	retCnd = FileRead(&fileIdx, rec, 1, &infiBlock, sizeof(t_infiBlock));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if((pcu != infiBlock.pcu[PCU_CH_A]) && (pcu != infiBlock.pcu[PCU_CH_B]))
		return(RT_FAILED);

	infiAddr.s_loop = infiBlock.loop;
    infiAddr.s_node = pcu;
    infiAddr.s_module = infiBlock.module;
    infiAddr.s_block = block;

    ZeroMemory(&replBuf, sizeof(READ_BLOCK_DATA));
	ZeroMemory(&m_buf, sizeof(t_spcdat));

    hr = ReadBlock(infiBlock.ici, &infiAddr, &replBuf);
	if(hr == R_NORMAL){
		retSt = DecodeFunctionCodeEx ((BYTE*) &replBuf.c_block_data, &m_buf);
		if(retSt != RT_NORMAL)
			return(retSt);
	}
    else{
		if(flag == TUNE_FROM_INFI)
			return(RT_FAILED);
		else{
			retSt = GetInfiBlockRecFromInfiAddr(block, &rec);
			if(retSt != RT_NORMAL)
				return(retSt);
			fileIdx.num = F_INBL;
			retCnd = FileRead(&fileIdx, rec, 1, &infiBlock, sizeof(t_infiBlock));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			*val = infiBlock.value;
			return(RT_NORMAL);
		}
	}

	*val = m_buf.rValue;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetInfiBlock
**
** Description:		Retrieve an infiBlock structure from F.INBL DAFS file
**
** Input			recNum		- Record number
**
** Output			block		- Block structure
**					
** Return:			RETSTAT		- RT_NORMAL	If block has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetInfiBlock(int recNum, t_infiBlock *block){
	RETCOND		retCnd;
	FILEIDX		fileIdx;

	fileIdx.num = F_INBL;

	if((recNum <= 0) || (recNum > N_MAX_BLOCKS))
		return(RT_FAILED);

	retCnd = FileRead(&fileIdx, recNum, 1, block, sizeof(t_infiBlock));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	if(block->ici == 0)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetInfiBlock
**
** Description:		Set an infiBlock structure from F.INBL DAFS file
**
** Input			block		- Infi block structure
**
** Output			---			- ---
**					
** Return:			RETSTAT		- RT_NORMAL	If block has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetInfiBlock(t_infiBlock block){
	RETCOND			retCnd;
	RETSTAT			retSt;
	t_infiBlock		dummyBlock;
	int				i;
	FILEIDX			fileIdx;
	bool			found;

	fileIdx.num = F_INBL;

	retSt = GetInfiBlockRecFromInfiAddr(block.block, &i);
	if(retSt != RT_NORMAL){
		found = false;
		for(i = 1; i <= N_MAX_BLOCKS; i++){
			retCnd = FileRead(&fileIdx, i, 1, &dummyBlock, sizeof(t_infiBlock));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			if(dummyBlock.ici == -1){
				found = true;
				break;
			}
		}
		if(!found)
			return(RT_FAILED);
	}
	
	retCnd = FileWrite(&fileIdx, i, 1, &block, sizeof(t_infiBlock));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitInfiBlockFile
**
** Description:		Initialize F.INBL DAFS file
**
** Input			---			- ---
**
** Output			---			- ---
**					
** Return:			RETSTAT		- RT_NORMAL	If F_INBL has been initilized
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitInfiBlockFile(void){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	t_infiBlock		block;
	int				i;

	fileIdx.num = F_INBL;

	ZeroMemory(&block, sizeof(t_infiBlock));
	for(i = 1; i <= N_MAX_BLOCKS; i++){
		retCnd = FileWrite(&fileIdx, i, 1, &block, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetInfiBlockNum
**
** Description:		Get the number of saved blocks
**
** Output			num			- number of saved blocks
**					
** Return:			RETSTAT		- RT_NORMAL	If number has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetInfiBlockNum(int *num){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	t_infiBlock		block;
	int				i;

	fileIdx.num = F_INBL;

	for(i = 1; i <= N_MAX_BLOCKS; i++){
		retCnd = FileRead(&fileIdx, i, 1, &block, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(block.block == 0){
			*num = i - 1;
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);

}

/*------------------------------------------------------------------------------
** Function:		GetInfiBlockRecFromDescr
**
** Description:		Retrieve an Infi90 block record number from its description
**
** Input			descr		- Infi90 block description
**
** Output			blockRec	- Block record number on F.INBL DAFS file
**					
** Return:			RETSTAT		- RT_NORMAL	If blockRec has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetInfiBlockRecFromDescr(TCHAR *descr, int *blockRec){
	RETCOND			retCnd;
	t_infiBlock		block;
	FILEIDX			fileIdx;
	int				rec;

	fileIdx.num = F_INBL;
	
	for(rec = 1; rec <= N_MAX_BLOCKS; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &block, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(block.ici == 0)
			return(RT_FAILED);
		if(!_tcscmp(block.descr, descr)){
			*blockRec = rec;
			return(RT_NORMAL);
		}
	}
	
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetInfiBlockRecFromInfiAddr
**
** Description:		Retrieve an Infi90 block record number from its address
**
** Input			block		- Infi90 address
**
** Output			blockRec	- Block record number on F.INBL DAFS file
**					
** Return:			RETSTAT		- RT_NORMAL	If blockRec has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetInfiBlockRecFromInfiAddr(int block, int *blockRec){
	RETCOND			retCnd;
	t_infiBlock		iBlock;
	FILEIDX			fileIdx;
	int				rec;

	fileIdx.num = F_INBL;
	
	for(rec = 1; rec <= N_MAX_BLOCKS; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &iBlock, sizeof(t_infiBlock));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(iBlock.ici == 0)
			break;
		if(iBlock.block == block){
			*blockRec = rec;
			return(RT_NORMAL);
		}
	}
	
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetLatchStatus
**
** Description:		Retrieve FA gripper latch status
**
** Input			mastType	- Mast to check
**
** Output			status		- FA gripper latch status (0 close, 1 open)
**					
** Return:			RETSTAT		- RT_NORMAL	If status has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetLatchStatus(GENIDX mastType, int *status){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;
	
	switch(mastType){
	case MAIN_MAST:
		retCnd = GetTagIdx(TWN_FAGRL_UNFIXED, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(GtBit((short)tagVal.value.val_di, 15) == 0)
			*status = 0;
		else
			*status = 1;
		return(RT_NORMAL);
		break;
	default:
		break;
	}
	return(RT_FAILED);
	
}

/*------------------------------------------------------------------------------
** Function:		GetMastOnObject
**
** Description:		Check if a mast is at object expected quote
**
** Input			mastType	- Mast to check
**
** Output			mastOnObj	- 1 if mast is on object
**								- 0 if mast is not on object
**					
** Return:			RETSTAT		- RT_NORMAL	If mastOnObj has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMastOnObject(GENIDX mastType, int *mastOnObj){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	switch(mastType){
	case MAIN_MAST:
		retCnd = GetTagIdx(TWN_MM_NOT_ON_OBJ, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(GtBit((short)tagVal.value.val_di, 15) == 0)
			*mastOnObj = 1;
		else
			*mastOnObj = 0;
		return(RT_NORMAL);
		break;
	default:
		break;
	}

	return(RT_FAILED);
}

/**********************************************************************************************/

/*------------------------------------------------------------------------------
** Function:		GetZone
**
** Description:		Retrieve a zone structure
**
** Input:			zoneIdx			- zone identifier
** Output:			zone			- zone struct
**
** Return:			RETSTAT			- RT_NORMAL	If zone has been retrireved
**									- RT_FAILED	otherwise
*/
RETSTAT GetZone(GENIDX zoneIdx, t_zone *zone){
	RETCOND		retCnd;
	FILEIDX		fileZone;

	fileZone.num = F_ZONE;

	
	retCnd = FileRead(&fileZone, zoneIdx, 1, zone, sizeof(t_zone));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
		
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetZone
**
** Description:		Set a zone structure
**
** Input:			zone			- zone struct
**
** Return:			RETSTAT			- RT_NORMAL	If zone has been retrireved
**									- RT_FAILED	otherwise
*/
RETSTAT SetZone(t_zone zone){
	RETCOND		retCnd;
	FILEIDX		fileZone;
	GENIDX		zoneIdx;
	int			rec;
	t_zone		tempZone;

	fileZone.num = F_ZONE;
	zoneIdx = 0;

	GetZoneIdx(zone.name, &zoneIdx);
	
	if(zoneIdx != 0){
		retCnd = FileWrite(&fileZone, zoneIdx, 1, &zone, sizeof(t_zone));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		return(RT_NORMAL);
	}
	else{
		for(rec = 1; rec <= N_MAX_ZONE; rec++){
			retCnd = FileRead(&fileZone, rec, 1, &tempZone, sizeof(t_zone));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			if(!_tcscmp(tempZone.name, _T(""))){
				retCnd = FileWrite(&fileZone, rec, 1, &zone, sizeof(t_zone));
				if(retCnd != R_NORMAL)
					return(RT_FAILED);
				return(RT_NORMAL);
			}
		}
		
	}
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		IsVirtualZoneIdx
**
** Description:		Retrieve a zone virtual flag from zone identifier
**
** Input:			zoneIdx			- zone identifier
** Output:			isVirt			- virtual zone flag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been retrireved
**									- RT_FAILED	otherwise
*/
RETSTAT IsVirtualZoneIdx(GENIDX zoneIdx, int *isVirt){
	RETSTAT		retSt;
	t_zone		zone;

	retSt = GetZone(zoneIdx, &zone);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	*isVirt = zone.virtualZone;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		IsVirtualZoneName
**
** Description:		Retrieve a zone virtual flag from zone name
**
** Input:			zoneName		- zone name
** Output:			isVirt			- virtual zone flag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been retrireved
**									- RT_FAILED	otherwise
*/
RETSTAT IsVirtualZoneName(ZONENAME zoneName, int *isVirt){
	RETSTAT		retSt;
	t_zone		zone;
	GENIDX		zoneIdx;

	retSt = GetZoneIdx(zoneName, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	retSt = GetZone(zoneIdx, &zone);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	*isVirt = zone.virtualZone;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		CheckSuperZone
**
** Description:		Check if a zone is contained in another zone
**
** Input:			zoneIdx			- zone identifier
**					superZoneIdx	- supposed superzone identifier
**
** Return:			RETSTAT			- RT_NORMAL	If zone is contained in superzone
**									- RT_NOSUBZONE If zone isn't contained in superzone
**									- RT_FAILED	otherwise
*/
RETSTAT CheckSuperZone(GENIDX zoneIdx, GENIDX superZoneIdx){
	RETSTAT		retSt;
	t_zone		zone;
	int			i;

	if(zoneIdx == superZoneIdx)
		return(RT_NORMAL);

	retSt = GetZone(superZoneIdx, &zone);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = 0; i < zone.n_subZones; i++){
		if(zone.subZones[i] == zoneIdx)
			return(RT_NORMAL);
	}

	return(RT_NOSUBZONE);
}

/*------------------------------------------------------------------------------
** Function:		CheckSuperZoneName
**
** Description:		Check if a zone is contained in another zone
**
** Input:			zoneName		- zone name
**					superZoneName	- supposed superzone name
**
** Return:			RETSTAT			- RT_NORMAL	If zone is contained in superzone
**									- RT_NOSUBZONE If zone isn't contained in superzone
**									- RT_FAILED	otherwise
*/
RETSTAT CheckSuperZoneName(ZONENAME zoneName, ZONENAME superZoneName){
	RETSTAT		retSt;
	t_zone		zone;
	int			i;
	GENIDX		zoneIdx;
	GENIDX		superZoneIdx;

	retSt = GetZoneIdx(zoneName, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdx(superZoneName, &superZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(zoneIdx == superZoneIdx)
		return(RT_NORMAL);

	retSt = GetZone(superZoneIdx, &zone);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = 0; i < zone.n_subZones; i++){
		if(zone.subZones[i] == zoneIdx)
			return(RT_NORMAL);
	}

	return(RT_NOSUBZONE);
}
/*------------------------------------------------------------------------------
** Function:		GetWideZoneIdx
**
** Description:		Retrieve the larger superzone conataining a zone
**
** Input:			zoneIdx			- zone identifier
** Output:			wideZoneIdx		- identifier of the larger zone that conatins zoneIdx
**
** Return:			RETSTAT			- RT_NORMAL	If wideZone exists
**									- RT_NOSUBZONE If zone isn't contained in superzone
**									- RT_FAILED	otherwise
*/
RETSTAT GetWideZoneIdx(GENIDX zoneIdx, GENIDX *wideZoneIdx){
	RETSTAT		retSt;
	GENIDX		tempZoneIdx;
	int			virtualFlag;
	ZONENAME	zoneName;
	int			level_1, level_2;

	*wideZoneIdx = 0;

	for(tempZoneIdx = 1; tempZoneIdx < N_MAX_ZONE; tempZoneIdx++){
		virtualFlag = 0;
		retSt = GetZoneName(tempZoneIdx, zoneName);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(!_tcscmp(zoneName, _T("")))
			break;
		retSt = IsVirtualZoneName(zoneName, &virtualFlag);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(virtualFlag){
			retSt = CheckSuperZone(zoneIdx, tempZoneIdx);
			if(retSt == RT_NORMAL){
				if(*wideZoneIdx == 0)
					*wideZoneIdx = tempZoneIdx;
				else{
					retSt = GetZoneLevel(*wideZoneIdx, &level_1);
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = GetZoneLevel(tempZoneIdx, &level_2);
					if(retSt != RT_NORMAL)
						return(retSt);
					if(level_2 < level_1)
						*wideZoneIdx = tempZoneIdx;
				}
			}
		}
	}
	if(*wideZoneIdx != 0)
		return(RT_NORMAL);
	else
		return(RT_NOSUBZONE);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneLevel
**
** Description:		Retrieve the larger superzone conataining a zone
**
** Input:			zoneIdx			- zone identifier
** Output:			level			- zone level
**
** Return:			RETSTAT			- RT_NORMAL	If level has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetZoneLevel(GENIDX	zoneIdx, int *level){
	RETSTAT		retSt;
	ZONENAME	zoneName;

	retSt = GetZoneName(zoneIdx, zoneName);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	*level = _tcslen(zoneName) - 1;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetConstraintPoint
**
** Description:		Retrieve the constraint point for an x,y movement
**
** Input:			sx				- source physical x
**					sy				- source physical y
**					dx				- dest. physical x
**					dy				- dest. physical y
** Output:			cx				- constarint physical x
**					cy				- constarint physical y
**
** Return:			RETSTAT			- RT_NORMAL	If point C has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetConstraintPoint(float sx, float sy, float dx, float dy, float *cx, float *cy){
	RETSTAT		retSt;
	GENIDX		sourceZoneIdx;
	GENIDX		destZoneIdx;
	bool		sourceZ21, sourceZ22, sourceZ23, destZ21, destZ22, destZ23;
	float		lh_x;
	float		lh_y;
	float		rb_x;
	float		rb_y;
	GENIDX		Z21Idx;
	GENIDX		Z22Idx;
	GENIDX		Z23Idx;

	sourceZ21 = false;
	sourceZ22 = false;
	sourceZ23 = false;
	destZ21 = false;
	destZ22 = false;
	destZ23 = false;

	*cx = 0.0;
	*cy = 0.0;
	lh_x = 0.0;
	lh_y = 0.0;
	rb_x = 0.0;
	rb_y = 0.0;

	retSt = GetZoneIdxMT(sx, sy, &sourceZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdxMT(dx, dy, &destZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdx(ZONE_FA, &Z21Idx);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	retSt = GetZoneIdx(ZONE_HECA, &Z22Idx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdx(ZONE_FFDS, &Z23Idx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = CheckSuperZone(sourceZoneIdx, Z21Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		sourceZ21 = true;

	retSt = CheckSuperZone(sourceZoneIdx, Z22Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		sourceZ22 = true;

	retSt = CheckSuperZone(sourceZoneIdx, Z23Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		sourceZ23 = true;
	
	retSt = CheckSuperZone(destZoneIdx, Z21Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		destZ21 = true;

	retSt = CheckSuperZone(destZoneIdx, Z22Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		destZ22 = true;

	retSt = CheckSuperZone(destZoneIdx, Z23Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);

	else if(retSt == R_NORMAL)
		destZ23 = true;

	retSt = GetZoneCoord(Z23Idx, &lh_x, &lh_y, &rb_x, &rb_y);
	if(retSt == RT_FAILED)
		return(RT_FAILED);

	if((sourceZ21 && destZ21) || (sourceZ22 && destZ22) || (sourceZ23 && destZ23))
		return(RT_NORMAL);

	if((!sourceZ21 && !sourceZ22 && !sourceZ23) || (!destZ21 && !destZ22 && !destZ23))
		return(RT_NORMAL);
	
	if((sourceZ23 && destZ22) || (sourceZ22 && destZ23)){
		*cx = (float)(lh_x);
		*cy = (float)(rb_y - 200.0);
		return(RT_NORMAL);
	}

	if((sourceZ22 && destZ21) || (sourceZ21 && destZ22)){
		*cx = (float)(rb_x + 100.0);
		*cy = (float)(rb_y - 100.0);
		return(RT_NORMAL);
	}

	if((sourceZ23 && destZ21) || (sourceZ21 && destZ23)){
		*cx = (float)(rb_x + 200.0);
		*cy = (float)(lh_y - 200.0);
		return(RT_NORMAL);
	}
	
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetConstraintPointEx
**
** Description:		Retrieve the constraint point for an x,y movement (revised for TV...)
**
** Input:			sx				- source physical x
**					sy				- source physical y
**					dx				- dest. physical x
**					dy				- dest. physical y
**					tvAngle			- tv angle at source
**
** Output:			cx				- constarint physical x
**					cy				- constarint physical y
**
** Return:			RETSTAT			- RT_NORMAL	If point C has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetConstraintPointEx(float sx, float sy, float dx, float dy, float tvAngle, float *cx, float *cy){
	/*
	RETSTAT			retSt;
	float			tvRadius;
	float			tvOffsetX;
	float			tvOffsetY;
	float			cosA;
	float			sinA;
	float			p03x;
	float			p03y;
	float			p04x;
	float			p04y;
	float			p09x;
	float			p09y;
	float			p10x;
	float			p10y;
	float			p11x;
	float			p11y;
	float			p12x;
	float			p12y;
	float			p13x;
	float			p13y;
	float			xInt;
	float			yInt;

	if(tvAngle == -1.0)
		tvRadius = 0.0;
	else{
		GetMMTVDistance(&tvRadius);
		sinA = 0.0;
		cosA = 0.0;
		sinA = (float)(sin((double)(tvAngle));
		cosA = (float)(cos((double)(tvAngle));
		if(((tvAngle >= (float)(0.0 - TOLL_MM)) && (tvAngle <= (float)(45.0 - TOLL_MM))) ||
		   ((tvAngle >= (float)(225.0 - TOLL_MM)) && (tvAngle <= (float)(315.0 - TOLL_MM)))){
			sy = sy - (float)(tvRadius * sinA);
			dy = dy - (float)(tvRadius * sinA);
			sx = sx - (float)(tvRadius * cosA);
			dx = dx - (float)(tvRadius * cosA);
		}
	}	

	retSt = GetInfiBlockValEx(8325, 0, TUNE_FROM_DAFS, &p03x);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetInfiBlockValEx(8331, 0, TUNE_FROM_DAFS, &p03y);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetInfiBlockValEx(8326, 0, TUNE_FROM_DAFS, &p04x);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	p04y = p03y;

	p09x = p04x;

	retSt = GetInfiBlockValEx(8334, 0, TUNE_FROM_DAFS, &p09y);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetInfiBlockValEx(8328, 0, TUNE_FROM_DAFS, &p10x);
	if(retSt != RT_NORMAL)
		return(retSt);

	p10y = p09y;

	p11x = p10x;

	retSt = GetInfiBlockValEx(8335, 0, TUNE_FROM_DAFS, &p11y);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetInfiBlockValEx(8329, 0, TUNE_FROM_DAFS, &p12x);
	if(retSt != RT_NORMAL)
		return(retSt);

	p12y = p11y;

	p13x = p03x;

	retSt = GetInfiBlockValEx(8336, 0, TUNE_FROM_DAFS, &p13y);
	if(retSt != RT_NORMAL)
		return(retSt);

	if((sx >= p10x) && (sx <= p12x) && (sy >= p10y) && (sy <= p12y)){
		yInt = sy + ((dy - sy) * (p12x - sx) / (dx - sx));
		
		if(yInt >= (float)(p12y - TOLL_GCP)){
			// ->| P12//
			if(dy <= p13y){
				
			
			}
			else{
			
			
			}
		}
	
	
	
	}

	return(RT_NORMAL);
	*/
	RETSTAT		retSt;
	GENIDX		sourceZoneIdx;
	GENIDX		destZoneIdx;
	bool		sourceZ21, sourceZ22, sourceZ23, destZ21, destZ22, destZ23;
	float		lh_x;
	float		lh_y;
	float		rb_x;
	float		rb_y;
	float		tvRadius;
	float		tvOffsetX;
	float		tvOffsetY;
	float		cosA;
	float		sinA;
	GENIDX		Z21Idx;
	GENIDX		Z22Idx;
	GENIDX		Z23Idx;

	sourceZ21 = false;
	sourceZ22 = false;
	sourceZ23 = false;
	destZ21 = false;
	destZ22 = false;
	destZ23 = false;

	if(tvAngle == -1.0){
		tvRadius = 0.0;
		tvOffsetY = 0.0;
		tvOffsetX = 0.0;
	}
	else{
		GetMMTVDistance(&tvRadius);
		sinA = 0.0;
		cosA = 0.0;
		sinA = (float)(sin((double)(tvAngle)));
		cosA = (float)(cos((double)(tvAngle)));
		if(((tvAngle >= (float)(0.0 - TOLL_MM)) && (tvAngle <= (float)(45.0 - TOLL_MM))) ||
		   ((tvAngle >= (float)(225.0 - TOLL_MM)) && (tvAngle <= (float)(315.0 - TOLL_MM)))){
			tvOffsetY = (float)(tvRadius * sinA);
			tvOffsetX = (float)(tvRadius * cosA);
		}
		else{
			tvOffsetY = 0.0;
			tvOffsetX = 0.0;
		}
	}	

	*cx = 0.0;
	*cy = 0.0;
	lh_x = 0.0;
	lh_y = 0.0;
	rb_x = 0.0;
	rb_y = 0.0;

	retSt = GetZoneIdxMT(sx, sy, &sourceZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdxMT(dx, dy, &destZoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdx(ZONE_FA, &Z21Idx);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	retSt = GetZoneIdx(ZONE_HECA, &Z22Idx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneIdx(ZONE_FFDS, &Z23Idx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = CheckSuperZone(sourceZoneIdx, Z21Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		sourceZ21 = true;

	retSt = CheckSuperZone(sourceZoneIdx, Z22Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		sourceZ22 = true;

	retSt = CheckSuperZone(sourceZoneIdx, Z23Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		sourceZ23 = true;
	
	retSt = CheckSuperZone(destZoneIdx, Z21Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		destZ21 = true;

	retSt = CheckSuperZone(destZoneIdx, Z22Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);
	else if(retSt == R_NORMAL)
		destZ22 = true;

	retSt = CheckSuperZone(destZoneIdx, Z23Idx);
	if(retSt == RT_FAILED)
		return(RT_FAILED);

	else if(retSt == R_NORMAL)
		destZ23 = true;

	retSt = GetZoneCoord(Z23Idx, &lh_x, &lh_y, &rb_x, &rb_y);
	if(retSt == RT_FAILED)
		return(RT_FAILED);

	if((sourceZ21 && destZ21) || (sourceZ22 && destZ22) || (sourceZ23 && destZ23))
		return(RT_NORMAL);

	if((!sourceZ21 && !sourceZ22 && !sourceZ23) || (!destZ21 && !destZ22 && !destZ23))
		return(RT_NORMAL);
	
	if((sourceZ23 && destZ22) || (sourceZ22 && destZ23)){
		*cx = (float)(lh_x + 500.0 + tvOffsetX);
		*cy = (float)(rb_y - 200.0 + tvOffsetY);
		return(RT_NORMAL);
	}

	if((sourceZ22 && destZ21) || (sourceZ21 && destZ22)){
		*cx = (float)(rb_x + 200.0 + tvOffsetX);
		*cy = (float)(rb_y - 500.0 + tvOffsetY);
		return(RT_NORMAL);
	}

	if((sourceZ23 && destZ21) || (sourceZ21 && destZ23)){
		*cx = (float)(rb_x + tvOffsetX);
		*cy = (float)(lh_y - tvOffsetY);
		return(RT_NORMAL);
	}
	
	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetDataSaveInfo
**
** Description:		Retrieve a data save info structure
**
** Input:			recNum			- DAFS file record number
**
** Output:			saveInfo		- data save info structure
**
** Return:			RETSTAT			- RT_NORMAL	If saveInfo has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetDataSaveInfo(int recNum, t_saveInfo *saveInfo){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	
	fileIdx.num = F_SAIN;

	if((recNum < 1) || (recNum > N_MAX_SAVEINFO))
		return(RT_FAILED);

	retCnd = FileRead(&fileIdx, recNum, 1, saveInfo, sizeof(t_saveInfo));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDataSaveInfo
**
** Description:		Save a data save info structure
**
** Input:			recNum			- DAFS file record number
**					saveInfo		- data save info structure
**
** Return:			RETSTAT			- RT_NORMAL	If saveInfo has been saved
**									- RT_FAILED	otherwise
*/
RETSTAT SetDataSaveInfo(int recNum, t_saveInfo saveInfo){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	int			rec;
	t_saveInfo	temp;
	
	fileIdx.num = F_SAIN;

	if(recNum != FIND_FIRST_FREE){
		if((recNum < 1) || (recNum > N_MAX_SAVEINFO))
			return(RT_FAILED);
	}
	if((recNum != SAVE_REC_AUTO) && (saveInfo.saveType == SAVE_TYPE_AUTO))
		return(RT_FAILED);
	if((recNum != SAVE_REC_AUTO_SIM) && (saveInfo.saveType == SAVE_TYPE_AUTO_SIM))
		return(RT_FAILED);
	else{
		if(saveInfo.saveType == SAVE_TYPE_AUTO)
			recNum = SAVE_REC_AUTO;
		else if(saveInfo.saveType == SAVE_TYPE_AUTO_SIM)
			recNum = SAVE_REC_AUTO_SIM;
		else{
			for(rec = 3; rec <= N_MAX_SAVEINFO; rec++){
				retCnd = FileRead(&fileIdx, rec, 1, &temp, sizeof(t_saveInfo));
				if(retCnd != R_NORMAL){
					return(RT_FAILED);
				}
				if(temp.saveTime.dwTime == 0){
					recNum = rec;
					break;
				}
			}
		}
	}
	retCnd = FileWrite(&fileIdx, recNum, 1, &saveInfo, sizeof(t_saveInfo));
	if(retCnd != R_NORMAL){
		return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ResetDataSaveInfo
**
** Description:		Reset a data save info structure
**
** Input:			recNum			- DAFS file record number
**
** Return:			RETSTAT			- RT_NORMAL	If recNum has been reset
**									- RT_FAILED	otherwise
*/
RETSTAT ResetDataSaveInfo(int recNum){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_saveInfo	temp;

	fileIdx.num = F_SAIN;
	ZeroMemory(&temp, sizeof(t_saveInfo));

	if((recNum < 3) || (recNum > N_MAX_SAVEINFO))
		return(RT_FAILED);

	retCnd = FileWrite(&fileIdx, recNum, 1, &temp, sizeof(t_saveInfo));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		sysInSimulation
**
** Description:		Check if system is in simulation mode
**
** Output:			flag			- 1 if system is in simulation
**
** Return:			RETSTAT			- RT_NORMAL	If falg has been set
**									- RT_FAILED	otherwise
*/
RETSTAT sysInSimulation(int *flag){
	RETCOND		retCnd;
	TAGIDX		tagSimIdx;
	TAGVALEX	tagSimVal;

	retCnd = GetTagIdx(TWN_SYS_STATUS, &tagSimIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagSimIdx, &tagSimVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);


	if(GtBit((short)tagSimVal.value.val_di, 15) == 1){
		*flag = 1;
		return(RT_NORMAL);
	}
	else if(GtBit((short)tagSimVal.value.val_di, 15) == 0){
		*flag = 0;
		return(RT_NORMAL);
	}
	else
		return(RT_FAILED);

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		sysInControl
**
** Description:		Check if system is in control mode
**
** Output:			flag			- 1 if system is in control
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been set
**									- RT_FAILED	otherwise
*/
RETSTAT sysInControl(int *flag){
	RETCOND		retCnd;
	TAGIDX		tagSimIdx;
	TAGVALEX	tagSimVal;

	retCnd = GetTagIdx(TWN_SYS_STATUS, &tagSimIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagSimIdx, &tagSimVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);


	if(GtBit((short)tagSimVal.value.val_di, 15) == 0){
		*flag = 1;
		return(RT_NORMAL);
	}
	else if(GtBit((short)tagSimVal.value.val_di, 15) == 1){
		*flag = 0;
		return(RT_NORMAL);
	}
	else
		return(RT_FAILED);

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetDynCurrentCont
**
** Description:		Retrieve container type present in Z1
**
** Output:			cont			- Container type
**
** Return:			RETSTAT			- RT_NORMAL	If cont has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetDynCurrentCont(GENIDX *cont){
/*
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
*/
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	retCnd = GetTagIdx(TWN_Z1_CONT_TYPE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

//	*cont = dyn.containerType;
	
	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	*cont = (GENIDX)(tagVal.value.val_float);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDynCurrentCont
**
** Description:		Retrieve container type present in Z1
**
** Input:			cont			- Container type
**
** Return:			RETSTAT			- RT_NORMAL	If cont has been set
**									- RT_FAILED	otherwise
*/
RETSTAT SetDynCurrentCont(GENIDX cont){
/*
	RETSTAT			retSt;
	RETCOND			retCnd;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);

	dyn.containerType = cont;

	retSt = SetDynStruc(dyn);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = GetTagIdx(TWN_Z1_CONT_TYPE, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	tagVal.value.val_float = (float)(cont);

	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
*/

	RETSTAT		retSt;
	RETCOND			retCnd;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;

	retSt = VotedTagWrite(TWN_Z1_CONT_TYPE, 0, (float)(cont), FLT_VALUE);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = GetTagIdx(TWN_U_CONTAINER, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	ZeroMemory(&tagVal.qual, sizeof(tagVal.qual));
	tagVal.qual.b.q1imp = 1;
	tagVal.value.val_float = (float)(cont);

	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetObjSipp
**
** Description:		Save sipping information in F_OBJE DAFS file
**
** Input:			objIdx			- Object identifier
**					sipp			- Sipping info data structure
**
** Return:			RETSTAT			- RT_NORMAL	If sipp has been saved
**									- RT_FAILED	otherwise
*/
RETSTAT SetObjSipp(GENIDX objIdx, t_sippRes sipp){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_obj		obj;
	
	fileIdx.num = F_OBJE;

	retCnd = FileRead(&fileIdx, objIdx, 1, &obj, sizeof(obj));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	memcpy(&obj.objSipp, &sipp, sizeof(t_sipp));

	retCnd = FileWrite(&fileIdx, objIdx, 1, &obj, sizeof(obj));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetObjSipp
**
** Description:		Retrieve sipping information in F_OBJE DAFS file
**
** Input:			objIdx			- Object identifier
**
** Output:			sipp			- Sipping info data structure
**
** Return:			RETSTAT			- RT_NORMAL	If sipp has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetObjSipp(GENIDX objIdx, t_sippRes *sipp){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_obj		obj;
	
	fileIdx.num = F_OBJE;

	retCnd = FileRead(&fileIdx, objIdx, 1, &obj, sizeof(obj));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	memcpy(sipp, &obj.objSipp, sizeof(t_sipp));

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetProgramTerminationOKFlag
**
** Description:		Read the ProgramTerminationOK flag from Windows registry 
**
** Output:			flag			- ProgramTerminationOK flag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been retrieved
**									- RT_FAILED	otherwise
*/
RETSTAT GetProgramTerminationOKFlag(int *flag){
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
    DWORD	dwBufLen;
	DWORD	val;
    
	size = 0;
	data = 0;
	type = 0;
	
	
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
				 TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Voldia"),
			     0,
				 KEY_QUERY_VALUE,
				 &hKey);
	res = RegQueryValueEx(hKey,
						  TEXT("ProgTerminationOK"),
						  NULL,
						  NULL,
						  (LPBYTE)&val,
						  &dwBufLen);
	if(res == ERROR_SUCCESS)
		*flag = val;
	else
		return(RT_FAILED);

	return(RT_NORMAL);	


}

/*------------------------------------------------------------------------------
** Function:		SetProgramTerminationOKFlag
**
** Description:		Set the ProgramTerminationOK flag in Windows registry 
**
** Input:			flag			- ProgramTerminationOK flag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been set
**									- RT_FAILED	otherwise
*/
RETSTAT SetProgramTerminationOKFlag(int flag){
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
    DWORD	dwBufLen;
    
	size = 0;
	data = 0;
	type = 0;
	
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
				 TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Voldia"),
			     0,
				 KEY_QUERY_VALUE,
				 &hKey);
	dwBufLen = sizeof(DWORD);
	res = RegSetValueEx(hKey,
						TEXT("ProgTerminationOK"),
						0,
						REG_DWORD,
						(LPBYTE)&flag,
						dwBufLen);
	if(res != ERROR_SUCCESS)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ConvertTntToAcad
**
** Description:		Convert a real value to an AutoCAd scale value
**
** Input:			tntVal			- real value to convert
**					valType			- value type	1)	bridge
**													2)	trolley
**													3)	FA gripper (tot and int)
**
** Return:			double			- Positive converted value
**									- -1 if errors occur
*/
double ConvertTntToAcad(double tntVal, int valType){
	double		tntOffSet;
	double		acadVal;

	switch(valType){
	case 1:
		if((tntVal < (double)(TNT_BRIDGE_MIN)) || (tntVal > (double)(TNT_BRIDGE_MAX)))
			return(-1);
		if(tntVal > (double)(TNT_CENTER_X)){
			tntOffSet = tntVal - (double)(TNT_CENTER_X);
			acadVal = tntOffSet * (((double)(ACAD_BRIDGE_MIN) - (double)(ACAD_CENTER_X)) / ((double)(TNT_BRIDGE_MAX) - (double)(TNT_CENTER_X)));
			return(acadVal);
		}
		else{
			tntOffSet = (double)(TNT_CENTER_X) - tntVal;
			acadVal = tntOffSet * (((double)(ACAD_BRIDGE_MAX) - (double)(ACAD_CENTER_X)) / ((double)(TNT_CENTER_X) - (double)(TNT_BRIDGE_MIN)));
			return(acadVal);
		}
		break;
	case 2:
		if((tntVal < (double)(TNT_TROLLEY_MIN)) || (tntVal > (double)(TNT_TROLLEY_MAX)))
			return(-1);
		if(tntVal > (double)(TNT_CENTER_Y)){
			tntOffSet = tntVal - (double)(TNT_CENTER_Y);
			acadVal = tntOffSet * (((double)(ACAD_TROLLEY_MAX) - (double)(ACAD_CENTER_Y)) / ((double)(TNT_TROLLEY_MAX) - (double)(TNT_CENTER_Y)));
			return(acadVal);
		}
		else{
			tntOffSet = (double)(TNT_CENTER_Y) - tntVal;
			acadVal = tntOffSet * (((double)(ACAD_TROLLEY_MIN) - (double)(ACAD_CENTER_Y)) / ((double)(TNT_CENTER_Y) - (double)(TNT_TROLLEY_MIN)));
			return(acadVal);
		}
		break;
	case 3:
		if((tntVal < (double)(TNT_FAGR_MIN)) || (tntVal > (double)(TNT_FAGR_MAX)))
			return(-1);
		acadVal = tntVal * (((double)(ACAD_FAGR_MAX) - (double)(ACAD_FAGR_MIN)) / ((double)(TNT_FAGR_MAX) - (double)(TNT_FAGR_MIN)));
		return(acadVal);
		break;
	default:
		return(-1);
		break;
	}
	return(-1);
}

/*------------------------------------------------------------------------------
** Function:		GetRPMB
**
** Description:		Retrieve a t_rpmb structure from F.RPMB file
**
** Input			recNum		- F.RPMB record number
**
** Output			rpmb		- t_rpmb structure at recNum							
**					
** Return:			RETSTAT		- RT_NORMAL	If rpmb has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetRPMB(int recNum, t_rpmb *rpmb){
	RETCOND		retCnd;
	FILEIDX		fileRpmb;

	fileRpmb.num = F_RPMB;

	if((recNum < 1) || (recNum > N_MAX_RPMB))
		return(RT_FAILED);

	retCnd = FileRead(&fileRpmb, recNum, 1, rpmb, sizeof(t_rpmb));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetRPMB
**
** Description:		Set a t_rpmb structure in F.RPMB file
**
** Input			recNum		- F.RPMB record number  (if 0 look for first free rec.)
**					rpmb		- t_rpmb structure to insert						
**					
** Return:			RETSTAT		- RT_NORMAL	If rpmb has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetRPMB(int recNum, t_rpmb rpmb){
	RETCOND		retCnd;
	RETSTAT		retSt;
	FILEIDX		fileRpmb;
	t_rpmb		dummy;
	int			rec;

	fileRpmb.num = F_RPMB;

	if((recNum < 0) || (recNum > N_MAX_RPMB))
		return(RT_FAILED);
	
	if(recNum == 0){
		for(rec = 1; rec <= N_MAX_RPMB; rec++){
			retSt = GetRPMB(rec, &dummy);			
			if(retSt != RT_NORMAL)
				return(RT_FAILED);
			if(dummy.movType == 0){
				retCnd = FileWrite(&fileRpmb, rec, 1, &rpmb, sizeof(t_rpmb));
				if(retCnd != R_NORMAL)
					return(RT_FAILED);
				return(RT_NORMAL);
			}
		}
		return(RT_FAILED);
	}
	else{
		retCnd = FileWrite(&fileRpmb, recNum, 1, &rpmb, sizeof(t_rpmb));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ResetRPMB
**
** Description:		Reset a F.RPMB file record
**
** Input			recNum		- F.RPMB record number to reset
**					
** Return:			RETSTAT		- RT_NORMAL	If recNum has been reset
**								- RT_FAILED	If errors occurred
*/
RETSTAT ResetRPMB(int recNum){
	RETSTAT		retSt;
	t_rpmb		dummy;
	if((recNum < 1) || (recNum > N_MAX_RPMB))
		return(RT_FAILED);

	ZeroMemory(&dummy, sizeof(t_rpmb));

	retSt = SetRPMB(recNum, dummy);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ResetRPMBFile
**
** Description:		Reset F.RPMB file 
**					
** Return:			RETSTAT		- RT_NORMAL	If F.RPMB has been reset
**								- RT_FAILED	If errors occurred
*/
RETSTAT ResetRPMBFile(void){
	RETSTAT		retSt;
	int			rec;

	for(rec = 1; rec <= N_MAX_RPMB; rec++){
			retSt = ResetRPMB(rec);
			if(retSt != RT_NORMAL)
				return(RT_FAILED);
	}
	return(RT_NORMAL);
}

/****************************************************************************************/
/*																						*/
/*	Function:		GetMovementInProgress												*/
/*																						*/
/*	Description:	Retrieve name and sp of the movement(s) in progress					*/
/*																						*/
/*	Output:			movement	-	String containing moving mechanism(s)				*/
/*					movIdx		-	Micro movement Idx									*/
/*					sp_1		-	First set point										*/
/*					sp_2		-	Second set point (two mechanism in operation)		*/
/*					pos_1		-	Start position										*/
/*					pos_2		-	Start position	(two mechanism in operation)		*/
/*																						*/
/*	Return:			RETSTAT		-	RT_NORMAL for normal finish							*/
/*									RT_INVMICR if no mechanism is in operation			*/
/*									RT_FAILED otherwise									*/
/*																						*/
/*	Author:			M. Tavella															*/
/*																						*/
/*	Date:			24/04/2002															*/
/*																						*/
/****************************************************************************************/
RETSTAT GetMovementInProgress(TCHAR movement[128], GENIDX *movIdx, float *sp_1, float *sp_2, float *pos_1, float *pos_2){
	RETCOND			retCnd;
	RETSTAT			retSt;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	bool			bridge;
	bool			trolley;
	bool			cantilever;

	bridge = false;
	trolley = false;
	cantilever = false;
	*sp_1 = SP_NULL;
	*sp_2 = SP_NULL;
	*pos_1 = SP_NULL;
	*pos_2 = SP_NULL;
	*movIdx = 0;

	retCnd = GetTagIdx(TWN_BRIDGE_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		bridge = true;
		retCnd = GetTagIdx(TWN_BRIDGE_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		
		retCnd = GetTagIdx(TWN_BRIDGE_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		
	}

	retCnd = GetTagIdx(TWN_TROLLEY_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		trolley = true;
		retCnd = GetTagIdx(TWN_TROLLEY_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		if(bridge){
			*sp_2 = tagVal.value.val_float;
			_stprintf_s(movement,sizeof(movement), _T("Bridge, Trolley"));
			retSt = GetMicroCmdIdx(MICRO_MOVEXY, movIdx);
		}
		else{
			*sp_1 = tagVal.value.val_float;
			_stprintf_s(movement,sizeof(movement), _T("Trolley"));
			retSt = GetMicroCmdIdx(MICRO_MOVEY, movIdx);
		}

		retCnd = GetTagIdx(TWN_TROLLEY_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		if(bridge)
			*pos_2 = tagVal.value.val_float;
		else
			*pos_1 = tagVal.value.val_float;
		return(RT_NORMAL);
	}

	
	if((bridge) && (!trolley)){
		_stprintf_s(movement,sizeof(movement), _T("Bridge"));
		retSt = GetMicroCmdIdx(MICRO_MOVEX, movIdx);
		return(RT_NORMAL);
	}
	
	retCnd = GetTagIdx(TWN_FAGR_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_FAGR_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Fuel Assembly gripper"));
		retSt = GetMicroCmdIdx(MICRO_MOVE_FAGR_MM, movIdx);
		retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;

		return(RT_NORMAL);
	}
	
	retCnd = GetTagIdx(TWN_FAGRL_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_FAGRL_FIX_REQ, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
			*sp_1 = SP_OPEN;
		else
			*sp_1 = SP_CLOSE;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Fuel Assembly gripper latch"));
		retSt = GetMicroCmdIdx(MICRO_MOVE_FAGRL_MM, movIdx);
		retCnd = GetTagIdx(TWN_FAGRL_FIXED, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
			*pos_1 = SP_OPEN;
		else
			*pos_1 = SP_CLOSE;

		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_CLGR_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_CLGR_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Cluster gripper"));
		retSt = GetMicroCmdIdx(MICRO_MOVE_CLGR_MM, movIdx);
		retCnd = GetTagIdx(TWN_CLGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_MM_ROT_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_MM_ROT_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Rotation"));
		retSt = GetMicroCmdIdx(MICRO_ROT_MM, movIdx);
		retCnd = GetTagIdx(TWN_MM_ROT_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_TVM_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_TVM_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("TV Mast"));
		retSt = GetMicroCmdIdx(MICRO_MOV_TV, movIdx);
		retCnd = GetTagIdx(TWN_TVM_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_TV_ROT_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_TV_ROT_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("TV Mast rotation"));
		retSt = GetMicroCmdIdx(MICRO_ROT_TV, movIdx);
		retCnd = GetTagIdx(TWN_TV_ROT_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_DISPL_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Main mast displacing"));
		retSt = GetMicroCmdIdx(MICRO_DISP_MM, movIdx);
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_SIPP_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Sipping"));
		retSt = GetMicroCmdIdx(MICRO_SIPP, movIdx);		
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(MICRO_CTRL_OP, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Fuel Assembly level control device"));
		retSt = GetMicroCmdIdx(MICRO_CTRL_OP, movIdx);
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_DIMP_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Device for FA seat inspection"));
		retSt = GetMicroCmdIdx(MICRO_DMP_OP, movIdx);	
		return(RT_NORMAL);
	}

	return(RT_INVMICR);
}

/****************************************************************************************/
/*																						*/
/*	Function:		GetMovementInProgressEx												*/
/*																						*/
/*	Description:	Retrieve name and sp of the movement(s) in progress					*/
/*																						*/
/*	Output:			movement	-	String containing moving mechanism(s)				*/
/*					movIdx		-	Micro movement Idx									*/
/*					sp_1		-	First set point										*/
/*					sp_2		-	Second set point (two mechanism in operation)		*/
/*					pos_1		-	Start position										*/
/*					pos_2		-	Start position	(two mechanism in operation)		*/
/*					movType		-	1 - horizontal movement								*/
/*									0 - vertical movement								*/
/*																						*/
/*	Return:			RETSTAT		-	RT_NORMAL for normal finish							*/
/*									RT_INVMICR if no mechanism is in operation			*/
/*									RT_FAILED otherwise									*/
/*																						*/
/*	Author:			M. Tavella															*/
/*																						*/
/*	Date:			24/04/2002															*/
/*																						*/
/****************************************************************************************/
RETSTAT GetMovementInProgressEx(TCHAR movement[128], GENIDX *movIdx, float *sp_1, float *sp_2, float *pos_1, float *pos_2, int *movType){
	RETCOND			retCnd;
	RETSTAT			retSt;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	bool			bridge;
	bool			trolley;
	bool			cantilever;

	bridge = false;
	trolley = false;
	cantilever = false;
	*sp_1 = SP_NULL;
	*sp_2 = SP_NULL;
	*pos_1 = SP_NULL;
	*pos_2 = SP_NULL;
	*movIdx = 0;
	*movType = 0;

	retCnd = GetTagIdx(TWN_BRIDGE_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		bridge = true;
		retCnd = GetTagIdx(TWN_BRIDGE_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		
		retCnd = GetTagIdx(TWN_BRIDGE_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;

		*movType = 1;
		
	}

	retCnd = GetTagIdx(TWN_TROLLEY_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		trolley = true;
		retCnd = GetTagIdx(TWN_TROLLEY_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		if(bridge){
			*sp_2 = tagVal.value.val_float;
			_stprintf_s(movement,sizeof(movement), _T("Bridge, Trolley"));
			retSt = GetMicroCmdIdx(MICRO_MOVEXY, movIdx);
		}
		else{
			*sp_1 = tagVal.value.val_float;
			_stprintf_s(movement,sizeof(movement), _T("Trolley"));
			retSt = GetMicroCmdIdx(MICRO_MOVEY, movIdx);
		}

		retCnd = GetTagIdx(TWN_TROLLEY_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		*movType = 1;

		if(bridge)
			*pos_2 = tagVal.value.val_float;
		else
			*pos_1 = tagVal.value.val_float;
		return(RT_NORMAL);
	}

	
	if((bridge) && (!trolley)){
		_stprintf_s(movement,sizeof(movement), _T("Bridge"));
		retSt = GetMicroCmdIdx(MICRO_MOVEX, movIdx);
		return(RT_NORMAL);
	}
	
	retCnd = GetTagIdx(TWN_FAGR_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_FAGR_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Fuel Assembly gripper"));
		retSt = GetMicroCmdIdx(MICRO_MOVE_FAGR_MM, movIdx);
		retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;

		*movType = 0;

		return(RT_NORMAL);
	}
	
	retCnd = GetTagIdx(TWN_FAGRL_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_FAGRL_FIX_REQ, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
			*sp_1 = SP_OPEN;
		else
			*sp_1 = SP_CLOSE;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Fuel Assembly gripper latch"));
		retSt = GetMicroCmdIdx(MICRO_MOVE_FAGRL_MM, movIdx);
		retCnd = GetTagIdx(TWN_FAGRL_FIXED, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		*movType = 0;

		if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
			*pos_1 = SP_OPEN;
		else
			*pos_1 = SP_CLOSE;

		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_CLGR_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_CLGR_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Cluster gripper"));
		retSt = GetMicroCmdIdx(MICRO_MOVE_CLGR_MM, movIdx);
		retCnd = GetTagIdx(TWN_CLGR_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		*movType = 0;

		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_MM_ROT_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_MM_ROT_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("Main Mast Rotation"));
		retSt = GetMicroCmdIdx(MICRO_ROT_MM, movIdx);
		retCnd = GetTagIdx(TWN_MM_ROT_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;

		*movType = 0;

		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_TVM_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_TVM_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("TV Mast"));
		retSt = GetMicroCmdIdx(MICRO_MOV_TV, movIdx);
		retCnd = GetTagIdx(TWN_TVM_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;

		*movType = 0;

		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_TV_ROT_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		retCnd = GetTagIdx(TWN_TV_ROT_SP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*sp_1 = tagVal.value.val_float;
		_stprintf_s(movement,sizeof(movement), _T("TV Mast rotation"));
		retSt = GetMicroCmdIdx(MICRO_ROT_TV, movIdx);
		retCnd = GetTagIdx(TWN_TV_ROT_POS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		*pos_1 = tagVal.value.val_float;
		
		*movType = 0;

		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_DISPL_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Main mast displacing"));
		retSt = GetMicroCmdIdx(MICRO_DISP_MM, movIdx);
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_SIPP_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Sipping"));
		retSt = GetMicroCmdIdx(MICRO_SIPP, movIdx);		
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(MICRO_CTRL_OP, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Fuel Assembly level control device"));
		retSt = GetMicroCmdIdx(MICRO_CTRL_OP, movIdx);
		return(RT_NORMAL);
	}

	retCnd = GetTagIdx(TWN_DIMP_MREQ, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		_stprintf_s(movement,sizeof(movement), _T("Device for FA seat inspection"));
		retSt = GetMicroCmdIdx(MICRO_DMP_OP, movIdx);	
		return(RT_NORMAL);
	}

	return(RT_INVMICR);
}

/****************************************************************************************/
/*																						*/
/*	Function:		IsMovementInProgress												*/
/*																						*/
/*	Description:	Chack if any movement in progress									*/
/*																						*/
/*	Output:			flag		-	Movement in progress flag							*/
/*																						*/
/*	Return:			RETSTAT		-	RT_NORMAL for normal finish							*/
/*									RT_FAILED otherwise									*/
/*																						*/
/*	Author:			M. Tavella															*/
/*																						*/														
/****************************************************************************************/
RETSTAT IsMovementInProgress(bool *flag){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	retCnd = GetTagIdx(TWN_START_MOV, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
		*flag = true;
	else
		*flag = false;

	return(RT_NORMAL);
}
/*------------------------------------------------------------------------------
** Function:		GetMicrDescrFromIdx
**
** Description:		Retrieve micro operation description from Idx
**
** Input:			mixrIdx		- micro command Idx
** Output:			descr		- micro command description
**
** Return:			RETSTAT		- RT_NORMAL	If descr has been found
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetMicrDescrFromIdx(GENIDX micrIdx, MIC_CMDDESC descr){
	RETCOND			retCnd;
	FILEIDX			fileMicr;
	t_micro_cmd		micr;
	int				i;
	
	fileMicr.num = F_MICR;

	for(i = 1; i <= N_MAX_MIC_CMD; i++){
		retCnd = FileRead(&fileMicr, micrIdx, 1, &micr, sizeof(micr));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		_tcscpy_s(descr,sizeof(descr), micr.descr);
		return(RT_NORMAL);
		
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		CheckMicroOp
**
** Description:		Check if a micro operation exists
**
** Input:			micrName	- micro operation name
**
** Return:			RETSTAT		- RT_NORMAL	If micrName exists
**								- RT_FAILED	otherwise
*/
RETSTAT CheckMicroOp(MIC_CMDNAME micrName){
	RETCOND			retCnd;
	FILEIDX			fileMicr;
	t_micro_cmd		micr;
	int				i;
	
	fileMicr.num = F_MICR;

	for(i = 1; i <= N_MAX_MIC_CMD; i++){
		retCnd = FileRead(&fileMicr, i, 1, &micr, sizeof(micr));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(!_tcscmp(micr.name, micrName)){
			return(RT_NORMAL);
		}
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetZoneDAFSFileIdx
**
** Description:		Retrieve cells DAFS file Idx from zone name 
**
** Input:			zoneName	- Zone name
**
** Output:			fileIdx		- Cells DAFS file Idx
**
** Return:			RETSTAT		- RT_NORMAL	If fileIdx has been found
**								- RT_FAILED	otherwise
*/
RETSTAT GetZoneDAFSFileIdx(ZONENAME zoneName, FILEIDX *fileIdx){
	RETSTAT		retSt;
	GENIDX		zoneIdx;
	int			virtFlag;

	virtFlag = 0;

	retSt = IsVirtualZoneName(zoneName, &virtFlag);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(virtFlag == 1)
		return(RT_FAILED);

	retSt = GetZoneIdx(zoneName, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	fileIdx->num = F_CE01 + zoneIdx - 1;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetCellDAFSFileRecord
**
** Description:		Retrieve the record number of a cell in a F.CExx DAFS file
**
** Input:			cellVx		- Cell virtual coordinate X
**					cellVy		- Cell virtual coordinate Y
**
** Output:			fileNum		- DAFS file number
**					recNum		- Record number
**
** Return:			RETSTAT		- RT_NORMAL	If recNum has been found
**								- RT_FAILED	otherwise
*/
RETSTAT GetCellDAFSFileRecord(short int cellVx, short int cellVy, int *fileNum, int *recNum){
	RETSTAT		retSt;
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	FILEINFO	fileInfo;
	GENIDX		zoneIdx;
	ZONENAME	zoneName;
	t_cell		cell;
	int			rec;

	retSt = GetZoneIdxVirtCoo(cellVx, cellVy, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneName(zoneIdx, zoneName);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZoneDAFSFileIdx(zoneName, &fileIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	*fileNum = fileIdx.num;

	retCnd = GetFileInfoEx(&fileIdx, &fileInfo);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	*recNum = 0;
	for(rec = 1; rec <= fileInfo.nrc; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			continue;

		if((cell.Virt_X == cellVx) && (cell.Virt_Y == cellVy)){
			*recNum = rec;
			break;
		}
	}

	if(*recNum == 0)
		return(RT_FAILED);

	return(RT_NORMAL);
}

RETSTAT GetMicrIdxFromName(MIC_CMDNAME micrName, GENIDX *micrIdx){
	RETCOND			retCnd;
	FILEIDX			fileMicr;
	t_micro_cmd		micr;
	int				i;
	
	fileMicr.num = F_MICR;
	*micrIdx = 0;

	for(i = 1; i <= N_MAX_MIC_CMD; i++){
		retCnd = FileRead(&fileMicr, i, 1, &micr, sizeof(micr));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		
		if(!_tcscmp(micr.name, micrName)){
			*micrIdx = i;
			return(RT_NORMAL);
		}	
	}

	return(RT_FAILED);
}

/*------------------------------------------------------------------------------
** Function:		GetMMFixSP
**
** Description:		Retrieve the set points for MM latch
**
** Output:			openSP			- Open set point
**					closeSP			- Close set point
**
** Return:			RETSTAT			- RT_NORMAL	If set points have been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetMMFixSP(float *openSP, float *closeSP){
	RETSTAT			retSt;
	RETCOND			retCnd;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	float			temp;

	retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retSt = GetInfiBlockValEx(8322, 0,TUNE_FROM_DAFS, &temp);
	if(retSt == RT_NORMAL)
		*openSP = (float)(tagVal.value.val_float + temp);
	else
		*openSP = (float)(OFFSET_FIX_OP + temp);

	retSt = GetInfiBlockValEx(8321, 0, TUNE_FROM_DAFS, &temp);
	if(retSt == RT_NORMAL)
		*closeSP = (float)(tagVal.value.val_float + temp);
	else
		*closeSP = (float)(OFFSET_FIX_CL + temp);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMastAngle
**
** Description:		Retrieve Main mast current angle
**
** Output:			angle		- main mast angle
**
** Return:			RETSTAT		- RT_NORMAL	If angle has been retrieved
**								- RT_FAILED	If errors occurred
** Modificata per utilizzo su NT.
*/
RETSTAT GetMastAngle(float *angle){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	retCnd = GetTagIdx(TWN_MM_ROT_POS, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	*angle = tagVal.value.val_float;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ConvertRetSt
**
** Description:		Convert RETSTAT error codes in error messages
**
** Input:			retSt		- error code
**
** Output:			errMsg		- error message
**
** Return:			RETSTAT		- RT_NORMAL	If errCode has been coverted
**								- RT_FAILED	If errors occurred
*/
RETSTAT ConvertRetSt(RETSTAT retSt, TCHAR errMsg[ERR_MSG_L]){
	switch(retSt){
	case RT_NORMAL:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Success"));
		break;
	case RT_FAILED:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Failed"));
		break;
    case RT_INVZONE:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid zone"));
		break;
    case RT_INVFORB:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid forbidden area"));
		break;
    case RT_INVCONF:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid configuration"));
		break;
    case RT_INVTOOL:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid tool"));
		break;
    case RT_INVMAST:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid mast"));
		break;
    case RT_INVOBJT:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid object type"));
		break;
    case RT_INVSOUR:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid source zone"));
		break;
    case RT_INVDEST:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid destination zone"));
		break;
    case RT_INVCONT:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid container in Zone 1"));
		break;
    case RT_INVCORR:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid corridor"));
		break;
    case RT_INVPATH:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid path between zones"));
		break;
    case RT_INVCOMP:
		break;
    case RT_INVMACC:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid macro oeration"));
		break;
    case RT_INVMICR:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid micro operation"));
		break;
    case RT_INVSEQ:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid movement sequence"));
		break;
    case RT_INVOBJ:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid object"));
		break;
    case RT_INVPHAS:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid phase"));
		break;
    case RT_INVCODE:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid code"));
		break;
    case RT_ILLMODE:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid operating mode"));
		break;
    case RT_NEXTMV:
		break;
    case RT_STARTPH:
		break;
    case RT_ENDSTEP:
		break;
    case RT_ERRSTEP:
		break;
    case RT_CHAUTO:
		break;
    case RT_CHSEMI:
		break;
    case RT_CHPROT:
		break;
    case RT_CHHCCN:
		break;
    case RT_CHCSCN:
		break;
    case RT_CHWSCN:
		break;
    case RT_CHMMMM:
		break;
    case RT_CHHCMM:
		break;
    case RT_STOPCP:
		break;
    case RT_RSTRCP:
		break;
    case RT_ILLCOND:
		break;
	case RT_NOSUBZONE:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Zone isn't a subzone"));
		break;
	case RT_NOROTALL:
		_stprintf_s(errMsg,sizeof(errMsg), _T("TV rotation is not allowed"));
		break;
	case RT_ERRINSR:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Error inserting object"));
		break;
	case RT_ERRREMO:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Error removing object"));
		break;
	case RT_NOLOGGEDUSER:
		_stprintf_s(errMsg,sizeof(errMsg), _T("No user currently logged"));
		break;
	case RT_NOTINMOVBUF:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Movement is not in movement buffer"));
		break;
	case RT_INVSPTM:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid sipping time"));
		break;
	default:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Dafault RETSAT message"));	
		break;
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ConvertRetPh
**
** Description:		Convert PHASTAT error codes in error messages
**
** Input:			retPh		- error code
**
** Output:			errMsg		- error message
**
** Return:			RETSTAT		- RT_NORMAL	If errCode has been coverted
**								- RT_FAILED	If errors occurred
*/
RETSTAT ConvertRetPh(PHASTAT retPh, TCHAR errMsg[ERR_MSG_L]){
	switch(retPh){
	case PH_NORMAL:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Success"));
		break;
    case PH_PRNCMP:		
		_stprintf_s(errMsg,sizeof(errMsg), _T("Previous Phase not Completed"));
		break;
    case PH_INVSOUR:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid Source in operation"));
		break;
    case PH_ERRSOUR:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Source not required in operation"));
		break;
    case PH_INVDEST:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid Destination in  operation"));
		break;
    case PH_ERRDEST:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Destination not required in operation"));
		break;
    case PH_INVMAC:		
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid macro operation"));
		break;
    case PH_INVOBJT:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid object type"));
		break;
    case PH_INVOBJ:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid object"));
		break;
    case PH_OBJMAC:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Object type not legal for operation"));
		break;
    case PH_OBJSOUR:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Object not legal for Source"));
		break;
    case PH_OBJDEST:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Object not legal for Destination"));
		break;
    case PH_OBJVIRT:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Illegal object in cell"));
		break;
    case PH_OBJTCON:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid container for object type"));
		break;
    case PH_OBJMASS:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid mast for this source zone"));
		break;
    case PH_OBJMASD:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid mast for this destination zoned"));
		break;
    case PH_OBJONMA:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Object already present on mast"));
		break;
    case PH_NESOUR:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Source virtual coordinates don't exist"));
		break;
    case PH_NEDEST:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Destination virtual coordinates don't exist"));
		break;
    case PH_NEPHCOO:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Phisical Coord. not in Zone"));
		break;
    case PH_DESTSOU:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Source and destimation zone don't collides"));
		break;
    case PH_MOVFORB:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Movement to a forbidden area"));
		break;
    case PH_SEQNOTF:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Movement sequence not found"));
		break;
    case PH_ERRPATH:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Error retrieveing legal path"));
		break;
    case PH_PHACTIV:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Opertation active"));
		break;
    case PH_DECLARE:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Operation is a \"Declare\""));
		break;
    case PH_INPROGR:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Operation in progress"));
		break;
    case PH_RESETNA:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Simulator reset not alloewd"));
		break;
	case PH_INVTECC:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid technological cycle"));
		break;
	case PH_EMPTYSRC:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Source is empty"));
		break;
	case PH_FULLDST:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Destination is full"));
		break;
	case PH_EMPTYDST:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Destination is empty"));
		break;
	case PH_CLHECA:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("FA with cluster moved to Hermetic Cask"));
		break;
	case PH_INVMAST:				
		_stprintf_s(errMsg,sizeof(errMsg), _T("Invalid mast used"));
		break;
	case PH_NOOBJMAST:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("No object on mast"));
		break;
	case PH_PLUGFULL:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Plug seats are full"));
		break;
	case PH_ERRADDPATH:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Error adding a path step."));
		break;
	case PH_FAILED:			
		_stprintf_s(errMsg,sizeof(errMsg), _T("Operation failed"));
		break;
	default:
		_stprintf_s(errMsg,sizeof(errMsg), _T("Dafault PHASTAT message"));
		break;
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetPhaseSipp
**
** Description:		Save sipping data in F.PHAS DAFS file
**
** Input:			phase		- phase number
**					sipp		- sipping data to save
**
** Return:			RETSTAT		- RT_NORMAL	If sipp has been saved
**								- RT_FAILED	If errors occurred
*/
/*
RETSTAT SetPhaseSipp(int phase, t_sipp sipp){
	RETSTAT		retSt;
	phas_struc	phas;

	retSt = GetPhase(phase, &phas);
	if(retSt != RT_NORMAL)
		return(retSt);

	memcpy(&phas.sipp, &sipp, sizeof(t_sipp));

	retSt = SetPhase(phas);
	if(retSt != RT_NORMAL)
		return(retSt);

	return(RT_NORMAL);
}
*/
/*------------------------------------------------------------------------------
** Function:		GetPhaseSipp
**
** Description:		Raad sipping data from F.PHAS DAFS file
**
** Input:			phase		- phase number
**
** Output:			sipp		- sipping data
**
** Return:			RETSTAT		- RT_NORMAL	If sipp has been retrieved
**								- RT_FAILED	If errors occurred
*/
/*
RETSTAT GetPhaseSipp(int phase, t_sipp *sipp){
	RETSTAT		retSt;
	phas_struc	phas;

	retSt = GetPhase(phase, &phas);
	if(retSt != RT_NORMAL)
		return(retSt);

	memcpy(sipp, &phas.sipp, sizeof(t_sipp));

	return(RT_NORMAL);
}
*/
/*------------------------------------------------------------------------------
** Function:		GetDynStopFlag
**
** Description:		Retrieve current dynamic stop flag value
**
** Output:			stopFlag	- stop flag
**
** Return:			RETSTAT		- RT_NORMAL	If stopFlag has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetDynStopFlag(int *stopFlag){
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	*stopFlag = dyn.stopFlag;

	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		SetDynStopFlag
**
** Description:		Set current dynamic stop flag value
**
** Input:			stopFlag	- stop flag
**
** Return:			RETSTAT		- RT_NORMAL	If stopFlag has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetDynStopFlag(int stopFlag){
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	dyn.stopFlag = stopFlag;

	retSt = SetDynStruc(dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetToMoveTags
**
** Description:		Set current dynamic stop flag value
**
** Input:			currOp		- current operation
**
** Return:			RETSTAT		- RT_NORMAL	If tag has been successfully set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetToMoveTags(short int currOp){
	RETSTAT			retSt;
	RETCOND			retCnd;
	GENIDX			fagrIdx;
	GENIDX			fagrlIdx;
	GENIDX			clgrIdx;
	GENIDX			mmRotIdx;
	GENIDX			tvInspIdx;
	OBJTCELL		cellSituation;
	OBJTMM			mastSituation;
	int				cellType;
	micro_cmd_exe	currMice;
	micro_cmd_exe	nextMice;
	micro_cmd_exe	nextMice_2;
	FILEIDX			fileIdx;

	fileIdx.num = F_MICE;

	retSt = GetMicroCmdIdx(MICRO_MOVE_FAGR_MM, &fagrIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicroCmdIdx(MICRO_MOVE_FAGRL_MM, &fagrlIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicroCmdIdx(MICRO_MOVE_CLGR_MM, &clgrIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicroCmdIdx(MICRO_ROT_MM, &mmRotIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicroCmdIdx(MICRO_TV_INSP, &tvInspIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMice(currOp, &currMice);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(currMice.movet == fagrIdx){
		if(currOp + 2 < N_MAX_MICENR){
			retCnd = FileRead(&fileIdx, currOp + 1, 1, &nextMice, sizeof(nextMice));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			if(nextMice.movet == tvInspIdx){
				retCnd = FileRead(&fileIdx, currOp + 3, 1, &nextMice, sizeof(nextMice));
				if(retCnd != R_NORMAL)
					return(RT_FAILED);
				//retCnd = FileRead(&fileIdx, currOp + 3, 1, &nextMice_2, sizeof(nextMice));
				//if(retCnd != R_NORMAL)
				//	return(RT_FAILED);
			}
			else{
				retCnd = FileRead(&fileIdx, currOp + 2, 1, &nextMice_2, sizeof(nextMice));
				if(retCnd != R_NORMAL)
					return(RT_FAILED);
			}
		}
		else
			return(RT_FAILED);

		retSt = GetCellType(currMice.Virt_X, currMice.Virt_Y, &cellType);
		if(retSt != RT_NORMAL)
			return(retSt);

		retSt = GetCellSituation(currMice.Virt_X, currMice.Virt_Y, &cellSituation);
		if(retSt != RT_NORMAL)
			return(retSt);

		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL)
			return(retSt);

		if((nextMice.movet == fagrlIdx) || (nextMice.movet == tvInspIdx)){
			if(cellType == CELL_FA){
				if((mastSituation.obj[OBJT_N_FA] != 0) || (cellSituation.obj[OBJT_N_FA] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FA_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((mastSituation.obj[OBJT_N_CLUS_FRM] != 0) || (cellSituation.obj[OBJT_N_CLUS_FRM] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_CLUSFRM_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
			else if((cellType == CELL_COVER_PLUG_EX) || (cellType == CELL_COVER_PLUG)){
				if(cellSituation.obj[OBJT_N_COVER] != 0){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if(cellSituation.obj[OBJT_N_FFDS_COV] != 0){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FFDS_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((cellSituation.obj[OBJT_N_CLUS_CAS] != 0) || (mastSituation.obj[OBJT_N_CLUS_CAS] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_CLUSCAS_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
			else if(cellType == CELL_HECA){
				if((nextMice_2.movet == mmRotIdx) && (cellSituation.obj[OBJT_N_COVER] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((nextMice_2.movet != mmRotIdx) && (cellSituation.obj[OBJT_N_COVER] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((nextMice_2.movet != mmRotIdx) && (cellSituation.obj[OBJT_N_COVER] == 0) && (cellSituation.obj[OBJT_N_HECA] == 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((nextMice_2.movet != mmRotIdx) && (cellSituation.obj[OBJT_N_COVER] == 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FA_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
			else if(cellType == CELL_FFDS_CASK){
				if((nextMice_2.movet == mmRotIdx) && (cellSituation.obj[OBJT_N_FFDS_COV] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FFDS_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((nextMice_2.movet != mmRotIdx) && (cellSituation.obj[OBJT_N_FFDS_COV] == 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FA_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
		}
		else if(nextMice.movet == clgrIdx){
			if(cellType == CELL_FA){
				if((cellSituation.obj[OBJT_N_CLUS] != 0) || (mastSituation.obj[OBJT_N_CLUS] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_CLUS_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
			else if(cellType == CELL_COVER_PLUG_EX){
				if((cellSituation.obj[OBJT_N_CLUS] != 0) || (mastSituation.obj[OBJT_N_CLUS] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_CLUS_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
		}
		else if(nextMice.movet == mmRotIdx){
			if(cellType == CELL_HECA){
				if((nextMice_2.movet == fagrlIdx) && (mastSituation.obj[OBJT_N_COVER] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
			else if((cellType == CELL_COVER_PLUG_EX) || (cellType == CELL_COVER_PLUG)){
				if((nextMice_2.movet == fagrlIdx) && (mastSituation.obj[OBJT_N_COVER] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
				else if((nextMice_2.movet == fagrlIdx) && (mastSituation.obj[OBJT_N_FFDS_COV] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FFDS_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
			else if(cellType == CELL_FFDS_CASK){
				if((nextMice_2.movet == fagrlIdx) && (mastSituation.obj[OBJT_N_FFDS_COV] != 0)){
					retSt = ResetObjectMoved();
					if(retSt != RT_NORMAL)
						return(retSt);
					retSt = VotedTagWrite(TWN_FFDS_PLUG_MOVE, 1, 0 , DIG_VALUE);
					if(retSt != RT_NORMAL)
						return(retSt);
					return(RT_NORMAL);
				}
			}
		}
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		ResetObjectMoved
**
** Description:		Reset object moved tags
**
** Return:			RETSTAT		- RT_NORMAL	If tags have been successfully reset
**								- RT_FAILED	If errors occurred
*/
RETSTAT ResetObjectMoved(void){
	RETSTAT			retSt;
	
	//Imposto a zero tutte le tag di tipo MOV.//
	//Tag per FA su MM//
	retSt = VotedTagWrite(TWN_FA_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	//Tag per Cluster su MM (Nomi tag non definitivi)//
	retSt = VotedTagWrite(TWN_CLUS_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
		
	//Tag per Hermetic Cask su MM (Nomi tag riferiti a Shipping Cask)//
	retSt = VotedTagWrite(TWN_HECA_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	//Tag per Hermetic Cask Cover su MM (Nomi tag non presenti)//
	retSt = VotedTagWrite(TWN_HECA_PLUG_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);	

	//Tag per Cluster Casing su MM (Nomi tag riferiti a cluster Jacket)//
	retSt = VotedTagWrite(TWN_CLUSCAS_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);		

	//Tag per FFDS Cask Cover su MM.//
	retSt = VotedTagWrite(TWN_FFDS_PLUG_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);
	
	//Tag per Cluster Frame su MM.//
	retSt = VotedTagWrite(TWN_CLUSFRM_MOVE, 0, 0, DIG_VALUE);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	return RT_NORMAL;
}

/*------------------------------------------------------------------------------
** Function:		GetFAHist
**
** Description:		Retrieve a FA history structure from DAFS file F.FAHI
**
** Input:			rec			- DAFS file record
** Output:			faHist		- FA history structure
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetFAHist(int rec, t_faHist *faHist){
	RETCOND		retCnd;
	FILEIDX		fileIdx;

	fileIdx.num = F_FAHI;

	retCnd = FileRead(&fileIdx, rec, 1, faHist, sizeof(t_faHist));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetFAHist
**
** Description:		Set a FA history structure on DAFS file F.FAHI
**
** Input:			faHist		- FA history structure
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetFAHist(t_faHist faHist){
	RETSTAT		retSt;
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_faHist	dummy;
	bool		found;
	int			rec;

	fileIdx.num = F_FAHI;

	retSt = GetFAHistRecFromIdx(faHist.faIdx, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(rec != -1){
		retCnd = FileWrite(&fileIdx, rec, 1, &faHist, sizeof(t_faHist));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	else{
		found = false;
		for(rec = 1; rec <= N_MAX_OBJ; rec++){
			retSt = GetFAHist(rec, &dummy);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(dummy.faIdx == 0){
				found = true;
				break;
			}
		}
		if(!found)
			return(RT_FAILED);
		retCnd = FileWrite(&fileIdx, rec, 1, &faHist, sizeof(t_faHist));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetFAHistRecFromIdx
**
** Description:		Retrieve a FA history structure from DAFS file F.FAHI
**
** Input:			faIdx		- Object FA unique identifier
** Output:			faHist		- FA history structure
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetFAHistRecFromIdx(GENIDX faIdx, int *rec){
	RETSTAT		retSt;
	t_faHist	faHist;
	int			tempRec;

	for(tempRec = 1; tempRec <= N_MAX_OBJ; tempRec++){
		retSt = GetFAHist(tempRec, &faHist);
		if(retSt != RT_NORMAL)
			return(retSt);

		if(faHist.faIdx == faIdx){
			*rec = tempRec;
			return(RT_NORMAL);
		}
	}

	*rec = -1;
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetFAHistRecFromName
**
** Description:		Retrieve a FA history structure from DAFS file F.FAHI
**
** Input:			faName		- Object FA name
** Output:			faHist		- FA history structure
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetFAHistRecFromName(OBJNAME faName, int *rec){
	RETSTAT		retSt;
	GENIDX		faIdx;

	retSt = GetObjIdx(faName, &faIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetFAHistRecFromIdx(faIdx, rec);
	if(retSt != RT_NORMAL)
		return(retSt);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetFAHistRecFromName
**
** Description:		Initialize a record of DAFS file F.FAHI
**
** Input:			rec			- DAFS filerecord to initialize
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitFAHistRec(int rec){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_faHist	dummy;

	fileIdx.num = F_FAHI;

	ZeroMemory(&dummy, sizeof(t_faHist));

	retCnd = FileWrite(&fileIdx, rec, 1, &dummy, sizeof(t_faHist));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitFAHistFile
**
** Description:		Initialize DAFS file F.FAHI
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitFAHistFile(void){
	RETSTAT		retSt;
	int			rec;

	for(rec = 1; rec <= N_MAX_OBJ; rec++){
		retSt = InitFAHistRec(rec);
		if(retSt != RT_NORMAL)
			return(retSt);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetFAHistDate
**
** Description:		Set a date on FA history file F.FAHI
**
** Input:			faIdx		- FA unique identifier
**					dateType	- Date to insert:
**									FAHI_DATE_Z1EXTR		
**									FAHI_DATE_Z2INST		
**									FAHI_DATE_Z3INST		
**									FAHI_DATE_Z3EXTR		
**									FAHI_DATE_Z2INST2		
**									FAHI_DATE_Z1INST	
**					flag		- FA operation result
**									FAHI_FLAG_OK
**									FAHI_FLAG_NOTOK
**					
**
** Return:			RETSTAT		- RT_NORMAL	If faHist has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetFAHistDate(GENIDX faIdx, int dateType, int flag){
	RETSTAT		retSt;
	RETCOND		retCnd;
	t_faHist	dummy;
	int			rec;


	retSt = GetFAHistRecFromIdx(faIdx, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(rec == -1)
		return(RT_FAILED);

	retSt = GetFAHist(rec, &dummy);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(dummy.faIdx != faIdx)
		return(RT_FAILED);

	if((flag != FAHI_FLAG_OK) && (flag != FAHI_FLAG_NOTOK))
		return(RT_FAILED);

	switch(dateType){
	case FAHI_DATE_Z1EXTR:
		retCnd = GetApmsTimeEx(&dummy.extrZ1Date);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		dummy.extrZ1Res = flag;
		break;
	case FAHI_DATE_Z2INST:
		retCnd = GetApmsTimeEx(&dummy.instZ2Date);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		dummy.instZ2Res = flag;
		break;
	case FAHI_DATE_Z3INST:
		retCnd = GetApmsTimeEx(&dummy.instZ3Date);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		dummy.instZ3Res = flag;
		break;
	case FAHI_DATE_Z3EXTR:
		retCnd = GetApmsTimeEx(&dummy.extrZ3Date);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		dummy.extrZ3Res = flag;
		break;
	case FAHI_DATE_Z2INST2:
		retCnd = GetApmsTimeEx(&dummy.inst2Z2Date);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		dummy.inst2Z2Res = flag;
		break;
	case FAHI_DATE_Z1INST:
		retCnd = GetApmsTimeEx(&dummy.instZ1Date);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		dummy.instZ1Res = flag;
		break;
	default:
		return(RT_FAILED);
	}

	retSt = SetFAHist(dummy);
	if(retSt != R_NORMAL)
		return(retSt);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitMNTNRec
**
** Description:		Initialize a record of DAFS file F.MNTN
**
** Input:			rec			- F.MNTN DAFS file record to initialize
**
** Return:			RETSTAT		- RT_NORMAL	If F.MNTN record has been initialized
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitMNTNRec(int rec){
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_maint		dummy;
	int			i;

	fileIdx.num = F_MNTN;

	ZeroMemory(&dummy, sizeof(t_maint));
	
	dummy.maintIdx;
	_stprintf_s(dummy.maintDescr, _T(""));
	dummy.microMovIdx = 0;
	dummy.lastExec.dwTime = 0;
	dummy.lastExec.dwMilsec = 0;
	dummy.result = MNTN_RES_NOT_EXE;
	for(i = 0; i < MNTN_RES_NUM; i++){
		dummy.result_i[i] = 0;
		dummy.result_f[i] = (float)(0);
	}
	dummy.userIdx = 0;

	retCnd = FileWrite(&fileIdx, rec, 1, &dummy, sizeof(t_maint));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		InitMNTNFile
**
** Description:		Initialize DAFS file F.MNTN
**
** Return:			RETSTAT		- RT_NORMAL	If F.MNTN has been initialized
**								- RT_FAILED	If errors occurred
*/
RETSTAT InitMNTNFile(void){
	RETSTAT		retSt;
	int			rec;

	for(rec = 1; rec <= MNTN_MAX_ENTRY; rec++){
		retSt = InitMNTNRec(rec);
		if(retSt != RT_NORMAL)
			return(retSt);
	}

	return(RT_NORMAL);
}

RETSTAT GetMNTN(int rec, t_maint *maint){
	RETCOND		retCnd;
	FILEIDX		fileIdx;

	fileIdx.num = F_MNTN;

	retCnd = FileRead(&fileIdx, rec, 1, maint, sizeof(t_maint));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetMNTNRecFromIdx
**
** Description:		Retrieve a maint structure record in DAFS file F.MNTN
**
** Input:			maintIdx	- maint object unique identifier
** Output:			rec			- maint object record number on F.MNTN
**
** Return:			RETSTAT		- RT_NORMAL	If rec has been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetMNTNRecFromIdx(GENIDX maintIdx, int *rec){
	RETSTAT		retSt;
	t_maint		maint;
	int			tempRec;

	for(tempRec = 1; tempRec <= MNTN_MAX_ENTRY; tempRec++){
		retSt = GetMNTN(tempRec, &maint);
		if(retSt != RT_NORMAL)
			return(retSt);

		if(maint.maintIdx == maintIdx){
			*rec = tempRec;
			return(RT_NORMAL);
		}
	}

	*rec = -1;
	return(RT_NORMAL);
}

RETSTAT SetMNTN(t_maint maint){
	RETSTAT		retSt;
	RETCOND		retCnd;
	FILEIDX		fileIdx;
	t_maint		dummy;
	bool		found;
	int			rec;

	fileIdx.num = F_MNTN;

	retSt = GetMNTNRecFromIdx(maint.maintIdx, &rec);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(rec != -1){
		retCnd = FileWrite(&fileIdx, rec, 1, &maint, sizeof(t_maint));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	else{
		found = false;
		for(rec = 1; rec <= MNTN_MAX_ENTRY; rec++){
			retSt = GetMNTN(rec, &dummy);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(dummy.maintIdx == 0){
				found = true;
				break;
			}
		}
		if(!found)
			return(RT_FAILED);
		retCnd = FileWrite(&fileIdx, rec, 1, &maint, sizeof(t_maint));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTagLimits
**
** Description:		Retrieve the high and low limits for a tag
**
** Input:			tagIdx		- Tag identifier to retrieve limits
** Output:			lowLim		- Tag low limit (instrumental)
**					highLim		- Tag high limit (instrumental)
**
** Return:			RETSTAT		- RT_NORMAL	If limits have been retrieved
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetTagLimits(TAGIDX tagIdx, float *lowLim, float *highLim){
	RETCOND		retCnd;
	TAGINFO		tagInfo;

	retCnd = GetTagInfo(&tagIdx, DB_VAL0, &tagInfo);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	else
		*lowLim = tagInfo.rValue;

	retCnd = GetTagInfo(&tagIdx, DB_VAL100, &tagInfo);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	else
		*highLim = tagInfo.rValue;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetZSetPoints
**
** Description:		Retrieve the Z set points for current FHM situation
**
** Output:			mastSp			- Mast set point
**					mastIntWeight	- Intermediate loose of weight quote
**					tvSp			- TV mast set point
**					mastTotWeight	- Mast total loose of weight
**
** Return:			RETSTAT			- RT_NORMAL	If sp have been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetZSetPoints(float *mastSp, float *mastIntWeight, float *tvSp, float *mastTotWeight){
	RETSTAT			retSt;
	RETCOND			retCnd;
	GENIDX			zoneIdx;
	GENIDX			seqIdx;
	GENIDX			fagrIdx;
	GENIDX			fagrlIdx;
	GENIDX			clgrIdx;
	GENIDX			mmRotIdx;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	OBJTMM			mastSituation;
	FILEIDX			fileIdx;
	MICRO_CMD		micrCmd;
	t_cell			cell;
	t_ope_seq		seq;
	int				vx;
	int				vy;
	int				movType;
	int				genObjType;
	int				i;
	bool			upward;
	bool			found;
	float			px;
	float			py;
	float			sp;
	float			pos;

	fileIdx.num = F_OSEQ;

	px = 0.0;
	py = 0.0;
	sp = 0.0;
	pos = 0.0;
	genObjType = -1;

	retSt = GetMastPosInfiSC(MAIN_MAST, &px, &py, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetZonePhisVirtCoord(px, py, &vx, &vy);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetCellVirtCoo(vx, vy, &cell);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = GetTagIdx(TWN_FAGR_SP, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	sp = tagVal.value.val_float;

	retCnd = GetTagIdx(TWN_FAGR_POS, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	pos = tagVal.value.val_float;

	if(pos > sp)
		upward = true;
	else
		upward = false;

	retSt = GetMastSituation(&mastSituation);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(!upward){
		if((mastSituation.obj[OBJT_N_CLUS_CAS] != 0) && (cell.objt_cell.obj[OBJT_N_CLUS] == 0)){
			if(mastSituation.obj[OBJT_N_CLUS] != 0){
				movType = MICRO_INSERT;
				retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else{
				movType = MICRO_INSERT;
				retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS_CAS], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
		}
		else if((mastSituation.obj[OBJT_N_CLUS_CAS] != 0) && (cell.objt_cell.obj[OBJT_N_CLUS] != 0)  /*&& (cell.objt_cell.obj[OBJT_N_COVER] != 0)*/){
			movType = MICRO_REMOVE;
			retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_CLUS], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_HECA] != 0){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_HECA], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_FFDS_COV] != 0){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_FFDS_COV], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_COVER] != 0){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_COVER], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_CLUS_FRM] != 0){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS_FRM], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_FA] != 0){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_FA], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else{
			if(cell.objt_cell.obj[OBJT_N_COVER] != 0){
				movType = MICRO_REMOVE;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_COVER], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if(cell.objt_cell.obj[OBJT_N_FFDS_COV] != 0){
				movType = MICRO_REMOVE;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_FFDS_COV], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if(cell.objt_cell.obj[OBJT_N_CLUS_FRM] != 0){
				movType = MICRO_REMOVE;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_CLUS_FRM], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if(cell.objt_cell.obj[OBJT_N_FA] != 0){
				movType = MICRO_REMOVE;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_FA], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if(cell.objt_cell.obj[OBJT_N_CLUS_CAS] != 0){
				movType = MICRO_REMOVE;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_CLUS_CAS], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
		}
	}
	else{
		if((mastSituation.obj[OBJT_N_CLUS_CAS] != 0) && (mastSituation.obj[OBJT_N_CLUS] == 0)){
			if(cell.objt_cell.obj[OBJT_N_CLUS] == 0){
				movType = MICRO_REMOVE;
				retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS_CAS], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else{
				movType = MICRO_INSERT;
				retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
		}
		else if((mastSituation.obj[OBJT_N_CLUS_CAS] != 0) && (mastSituation.obj[OBJT_N_CLUS] != 0)){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if((mastSituation.obj[OBJT_N_CLUS_CAS] == 0) && (cell.objt_cell.obj[OBJT_N_CLUS_CAS] != 0)){
			movType = MICRO_INSERT;
			retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_CLUS_CAS], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_HECA] != 0){
			movType = MICRO_REMOVE;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_HECA], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_COVER] != 0){
			movType = MICRO_REMOVE;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_COVER], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_FFDS_COV] != 0){
			movType = MICRO_REMOVE;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_FFDS_COV], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_CLUS_FRM] != 0){
			movType = MICRO_REMOVE;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_CLUS_FRM], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(mastSituation.obj[OBJT_N_FA] != 0){
			movType = MICRO_REMOVE;
			retSt = GetObjtGenericTypeCode(mastSituation.obj[OBJT_N_FA], &genObjType);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else{
			if(cell.objt_cell.obj[OBJT_N_COVER] != 0){
				movType = MICRO_INSERT;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_COVER], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if(cell.objt_cell.obj[OBJT_N_FFDS_COV] != 0){
				movType = MICRO_INSERT;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_FFDS_COV], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if(cell.objt_cell.obj[OBJT_N_FA] != 0){
				movType = MICRO_INSERT;
				retSt = GetObjtGenericTypeCode(cell.objt_cell.obj[OBJT_N_FA], &genObjType);
				if(retSt != RT_NORMAL)
					return(retSt);
			}	
		}
	}

	retSt = GetSeqIdx(movType, genObjType, MAIN_MAST, zoneIdx, cell.type, &seqIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicrIdxFromName(MICRO_MOVE_FAGR_MM, &fagrIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicrIdxFromName(MICRO_MOVE_FAGRL_MM, &fagrlIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicrIdxFromName(MICRO_MOVE_CLGR_MM, &clgrIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetMicrIdxFromName(MICRO_ROT_MM, &mmRotIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = FileRead(&fileIdx, seqIdx, 1, &seq, sizeof(t_ope_seq));
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	/*
	ZeroMemory(&micrCmd, sizeof(MICRO_CMD));
	if(!upward){
		opIdx = -1;
		for(i = 0; i < seq.micro_op_num; i++){
			if((seq.micro_cmd[i].mic_name == fagrlIdx) || (seq.micro_cmd[i].mic_name == clgrIdx)){
				opIdx = i - 1;
				break;
			}
		}

		if(opIdx == -1)
			return(RT_FAILED);
		else
			memcpy(&micrCmd, &seq.micro_cmd[opIdx].mic_name, sizeof(MICRO_CMD));
	}
	else{
		if(seq.micro_cmd[seq.micro_op_num - 1].mic_name == fagrIdx)
			memcpy(&micrCmd, &seq.micro_cmd[seq.micro_op_num - 1].mic_name, sizeof(MICRO_CMD));
		else
			return(RT_FAILED);
	}

	*mastSp = micrCmd.quota[0];
	*mastIntWeight = micrCmd.quota[1];
	*tvSp = micrCmd.quota[2];
	*mastIntSlow = micrCmd.quota[3];
	*/
	ZeroMemory(&micrCmd, sizeof(MICRO_CMD));
	if(!upward){
		found = false;
		for(i = 0; i < seq.micro_op_num; i++){
			if((seq.micro_cmd[i].mic_name == fagrIdx) && ((seq.micro_cmd[i + 1].mic_name == fagrlIdx) || (seq.micro_cmd[i + 1].mic_name == clgrIdx) || (seq.micro_cmd[i + 1].mic_name == mmRotIdx))){
				found = true;
				break;
			}
		}
		if(found)
			memcpy(&micrCmd, &seq.micro_cmd[i], sizeof(MICRO_CMD));
		else
			return(RT_FAILED);
	}
	else{
		if(seq.micro_cmd[seq.micro_op_num - 1].mic_name == fagrIdx)
			memcpy(&micrCmd, &seq.micro_cmd[seq.micro_op_num - 1], sizeof(MICRO_CMD));
		else
			return(RT_FAILED);
	}

	*mastSp = micrCmd.quota[0];
	*mastIntWeight = micrCmd.quota[1];
	*tvSp = micrCmd.quota[3];
	*mastTotWeight = micrCmd.quota[2];

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTagQuality
**
** Description:		Retrieve a tag quality from tag name.
**
** Input:			tagName			- Tag name
**
** Output:			tagQual			- Tag quality
**
** Return:			RETSTAT			- RT_NORMAL	If tagQual has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetTagQuality(TAGNAME tagName, QUAL *tagQual){
	RETCOND		retCnd;
	RETSTAT		retSt;
	TAGIDX		tagIdx;

	retCnd = GetTagIdx(tagName, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retSt = GetTagQualityIdx(tagIdx, tagQual);
	if(retSt != RT_NORMAL)
		return(retSt);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetTagQualityIdx
**
** Description:		Retrieve a tag quality from tag idx.
**
** Input:			tagIdx			- Tag identifier
**
** Output:			tagQual			- Tag quality
**
** Return:			RETSTAT			- RT_NORMAL	If tagQual has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetTagQualityIdx(TAGIDX tagIdx, QUAL *tagQual){
	RETCOND			retCnd;
	TAGVALEX		tagVal;

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	memcpy(tagQual, &tagVal.qual, sizeof(QUAL));

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		IsGood
**
** Description:		Check a Tag quality
**
** Input:			tagName			- Tag name
**
** Output:			flag			- Good quality flag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT IsGood(TAGNAME tagName, bool *flag){
	RETSTAT			retSt;
	QUAL			qual;
	int				i;
	bool			val;

	retSt = GetTagQuality(tagName, &qual);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = LO_BIT_INDEX; i <= HI_BIT_INDEX; i++){
		retSt = GetBitValue(qual.l, i, &val);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(i == BIT_Q1_IMPL){
			if(val)
				*flag = true;
			else
				*flag = false;
		}
		else{
			if(val){
				*flag = false;
				return(RT_NORMAL);
			}
		}
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		IsGoodIdx
**
** Description:		Check a Tag quality from tag idx.
**
** Input:			tagIdx			- Tag identifier
**
** Output:			flag			- Good quality flag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT IsGoodIdx(TAGIDX tagIdx, bool *flag){
	RETSTAT			retSt;
	QUAL			qual;
	int				i;
	bool			val;

	retSt = GetTagQualityIdx(tagIdx, &qual);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = LO_BIT_INDEX; i <= HI_BIT_INDEX; i++){
		retSt = GetBitValue(qual.l, i, &val);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(i == BIT_Q1_IMPL){
			if(val)
				*flag = true;
			else
				*flag = false;
		}
		else{
			if(val){
				*flag = false;
				return(RT_NORMAL);
			}
		}
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		TagFailure
**
** Description:		Retrieve tag failure type
**
** Input:			tagName			- Tag name
**
** Output:			index			- Failure type
**
** Return:			RETSTAT			- RT_NORMAL	If index has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT TagFailure(TAGNAME tagName, int *index){
	RETSTAT			retSt;
	QUAL			qual;
	int				i;
	bool			val;

	retSt = GetTagQuality(tagName, &qual);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = LO_BIT_INDEX; i <= HI_BIT_INDEX; i++){
		retSt = GetBitValue(qual.l, i, &val);
		if(retSt != RT_NORMAL)
			return(retSt);
	
		if(val){
			*index = i;
			return(RT_NORMAL);
		}
		
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		TagFailureIdx
**
** Description:		Retrieve tag failure type from index
**
** Input:			tagName			- Tag name
**
** Output:			index			- Failure type
**
** Return:			RETSTAT			- RT_NORMAL	If index has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT TagFailureIdx(TAGIDX tagIdx, int *index){
	RETSTAT			retSt;
	QUAL			qual;
	int				i;
	bool			val;

	retSt = GetTagQualityIdx(tagIdx, &qual);
	if(retSt != RT_NORMAL)
		return(retSt);

	for(i = LO_BIT_INDEX; i <= HI_BIT_INDEX; i++){
		retSt = GetBitValue(qual.l, i, &val);
		if(retSt != RT_NORMAL)
			return(retSt);
	
		if(val){
			*index = i;
			return(RT_NORMAL);
		}
		
	}
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetGood
**
** Description:		Set a tag quality to GOOD
**
** Input:			tagName			- Tag name
**					voted			- Tag is managed by Voter
**
** Return:			RETSTAT			- RT_NORMAL	If quality has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetGood(TAGNAME tagName, bool voted){
	RETCOND			retCnd;
	RETSTAT			retSt;
	TAGIDX			tagIdx;

	retCnd = GetTagIdx(tagName, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retSt = SetGoodIdx(tagIdx, voted);
	
	return(retSt);
}

/*------------------------------------------------------------------------------
** Function:		SetGoodIdx
**
** Description:		Set a tag quality to GOOD
**
** Input:			tagIdx			- Tag identifier
**					voted			- Tag is managed by Voter
**
** Return:			RETSTAT			- RT_NORMAL	If quality has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetGoodIdx(TAGIDX tagIdx, bool voted){
	RETCOND			retCnd;
	RETSTAT			retSt;
	TAGINFO			tagInfo;
	TAGVALEX		tagVal;
	QUAL			qual;
//	int				i;
//	bool			val;

	retCnd = GetTagInfo(&tagIdx, DB_TAGNAME, &tagInfo);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	/*
	for(i = LO_BIT_INDEX; i <= HI_BIT_INDEX; i++){
		if(i == BIT_Q1_IMPL)
			val = true;
		else
			val = false;
		retSt = SetBitValue((int *)&qual.l, i, val);
		if(retSt != RT_NORMAL)
			return(retSt);
	}
	*/
	qual.l = QUAL_GOOD;
	
	if(voted){
		retSt = VotedTagWriteQual(tagInfo.szValue, qual);
		if(retSt != RT_NORMAL)
			return(RT_FAILED);
	}
	else{
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		memcpy(&tagVal.qual, &qual, sizeof(QUAL));
		retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_DIRECT);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetGoodQual
**
** Description:		Set a tag quality to GOOD
**
** Input:			tagVal			- Tag value
**
** Return:			RETSTAT			- RT_NORMAL	If quality has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetGoodQual(TAGVALEX *tagVal){
	RETSTAT			retSt;
	int				i;
	bool			val;
	
	for(i = LO_BIT_INDEX; i <= HI_BIT_INDEX; i++){
		if(i == BIT_Q1_IMPL)
			val = true;
		else
			val = false;
		retSt = SetBitValue((int *)(tagVal->qual.l), i, val);
		if(retSt != RT_NORMAL)
			return(retSt);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetBitValue
**
** Description:		Retrieve a bit value in a integer
**
** Input:			datValue		- Integer input
**					bitIndex		- Bit index (0 -31)
**
** Output:			bitValue		- Selected bit value
**
** Return:			RETSTAT			- RT_NORMAL	If bitValue has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetBitValue(int datValue, int bitIndex, bool *bitValue){
	int			bitMask;

	if((bitIndex < LO_BIT_INDEX) || (bitIndex > HI_BIT_INDEX))
		return(RT_FAILED);

	bitMask = (int)(pow(2.0, bitIndex));

	datValue &= bitMask;

	if(datValue == bitMask)
		*bitValue = true;
	else
		*bitValue = false;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetBitValue
**
** Description:		Set a bit value in a integer
**
** Input:			datValue		- Integer input
**					bitIndex		- Bit index (0 -31)
**					bitValue		- Bit value
**
** Return:			RETSTAT			- RT_NORMAL	If bitValue has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetBitValue(int *datValue, int bitIndex, bool bitValue){
	int			bitMask;
	int			revBitMask;
	int			temp;
	bool		currValue;

	if((bitIndex < LO_BIT_INDEX) || (bitIndex > HI_BIT_INDEX))
		return(RT_FAILED);

	temp = (int)(*datValue);

	GetBitValue(temp, bitIndex, &currValue);

	if(currValue == bitValue)
		return(RT_NORMAL);

	bitMask = (int)(pow(2.0, bitIndex));
	revBitMask =~ bitMask;
	if(bitValue == true)
		temp |= bitMask;
	else
		temp &= revBitMask;

	datValue = &temp;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetStationID
**
** Description:		Retrieve the station ID from the registry
**
** Output:			ID				- Station ID
**
** Return:			RETSTAT			- RT_NORMAL	If ID has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetStationID(int *ID){
	LONG			res;
	LPDWORD			type;
	LPBYTE			data;
	LPDWORD			size;
	HKEY			hKey;
    DWORD			dwBufLen;
	DWORD			val;
    
	size = 0;
	data = 0;
	type = 0;
		
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
				 TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Voldia"),
			     0,
				 KEY_QUERY_VALUE,
				 &hKey);
	dwBufLen = sizeof(DWORD);	
	res = RegQueryValueEx(hKey,
						  TEXT("Station"),
						  NULL,
						  NULL,
						  (LPBYTE)&val,
						  &dwBufLen);
	if(res == ERROR_SUCCESS)
		*ID = val;
	else
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetStationTCFlag
**
** Description:		Retrieve the value of the station interlock tag
**
** Input:			station			- Station number
**
** Output:			flag			- Value of the station interlock tag
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetStationTCFlag(int station, int *flag){
	RETCOND		retCnd;
	TAGVALEX	tagVal;
	TAGIDX		tagIdx;

	if(station == STATION_1){
		retCnd = GetTagIdx(TWN_STATION_INT_1, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}
	else if(station == STATION_2){
		retCnd = GetTagIdx(TWN_STATION_INT_2, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}else
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	*flag = (int)(tagVal.value.val_float);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetStationTCFlag
**
** Description:		Set the number of the station on station interlock tag
**
** Input:			status			- Station status to set	-	SIM_NO_TC
**																SIM_TC			
**																CTRL_NO_TC
**																CTRL_TC
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT SetStationTCFlag(void){
	RETSTAT			retSt;
	int				station;
	int				flag;
	int				inSim;
    
	retSt = GetStationID(&station);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	if(station == STATION_1){
		sysInSimulation(&inSim);
		if(inSim == 0){
			retSt = GetStationTCFlag(STATION_2, &flag);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(flag == CTRL_TC)
				return(RT_FAILED);
			retSt = VotedTagWrite(TWN_STATION_INT_1, 0, (float)(CTRL_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else{
			retSt = VotedTagWrite(TWN_STATION_INT_1, 0, (float)(SIM_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
	}
	else if(station == STATION_2){
		retSt = GetStationTCFlag(STATION_1, &flag);
		if(retSt != RT_NORMAL)
			return(retSt);
		if(flag == CTRL_TC)
			return(RT_FAILED);
		retSt = VotedTagWrite(TWN_STATION_INT_2, 0, (float)(CTRL_TC), FLT_VALUE);
		if(retSt != RT_NORMAL)
			return(retSt);
	}
	else
		return(RT_FAILED);

	return(RT_NORMAL);
}

RETSTAT ClearStationTCFlag(void){
	RETSTAT			retSt;
	int				station;
	int				flag;
	int				ctrl;
    
	retSt = sysInControl(&ctrl);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetStationID(&station);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = GetStationTCFlag(station, &flag);
	if(retSt != RT_NORMAL)
		return(retSt);

	if((flag == SIM_NO_TC) || (flag == CTRL_NO_TC))
		return(RT_NORMAL);
	
	if(ctrl == 0){
		if(station == STATION_1){
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(SIM_NO_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(station == STATION_2){
			retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(SIM_NO_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else
			return(RT_FAILED);
	}
	else if(ctrl == 1){
		if(station == STATION_1){
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_NO_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else if(station == STATION_2){
			retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_NO_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		else
			return(RT_FAILED);
	}
	
	return(RT_NORMAL);
}

RETSTAT InitManualFlags(void){
	RETSTAT			retSt;

	retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
	if(retSt != RT_NORMAL)
		return(retSt);

	retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
	if(retSt != RT_NORMAL)
		return(retSt);

	return(RT_NORMAL);
}

RETSTAT InitAutoFlags(void){
	RETSTAT			retSt;
	int				station;
	int				ctrl;

	retSt = GetStationID(&station);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(station == STATION_1){
		retSt = sysInControl(&ctrl);
		if(retSt != RT_NORMAL)
			return(retSt);

		if(ctrl){
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_NO_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}else{
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(SIM_NO_TC), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
	}else{
		retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_NO_TC), FLT_VALUE);
		if(retSt != RT_NORMAL)
			return(retSt);
	}

	return(RT_NORMAL);

}

RETSTAT SetMasterStation(int station){
	RETSTAT			retSt;
	int				local;
	int				ctrl;
    
	retSt = GetStationID(&local);
	if(retSt != RT_NORMAL)
		return(retSt);

	if(local == STATION_1){
		retSt = sysInControl(&ctrl);
		if(retSt != RT_NORMAL)
			return(retSt);

		if(ctrl){
			if(station == STATION_1){
				retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_MAN_MASTER), FLT_VALUE);
				if(retSt != RT_NORMAL)
					return(retSt);
				retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else if(station == STATION_2){
				retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_MAN_MASTER), FLT_VALUE);
				if(retSt != RT_NORMAL)
					return(retSt);
				retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else
				return(RT_FAILED);
		}else{
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}
		
	}else{
		if(station == STATION_1){
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_MAN_MASTER), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
			retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}else if(station == STATION_2){
			retSt = VotedTagWriteEx(TWN_STATION_INT_2, 0, (float)(CTRL_MAN_MASTER), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
			retSt = VotedTagWriteEx(TWN_STATION_INT_1, 0, (float)(CTRL_MAN_SLAVE), FLT_VALUE);
			if(retSt != RT_NORMAL)
				return(retSt);
		}else
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

RETSTAT SetStationTag(void){
	RETSTAT			retSt;
	RETCOND			retCnd;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	int				local;
    
	retSt = GetStationID(&local);
	if(retSt != RT_NORMAL)
		return(retSt);

	retCnd = GetTagIdx(TWN_STATION, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);
	
	ZeroMemory(&tagVal, sizeof(TAGVALEX));

	tagVal.qual.b.q1imp = 1;
	tagVal.value.val_di = local;

	retCnd = TagWrite(&tagIdx, &tagVal, TAGWRITE_STD);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);
}
/*------------------------------------------------------------------------------
** Function:		GetTripInfo
**
** Description:		Check if a trip is currently active, and return info
**
** Input:			---				- ---
**
** Output:			flag			-	TRIP_OFF
**										TRIP_ALL
**										TRIP_BRIDGE	
**										TRIP_TROLLEY
**										TRIP_MM
**										TRIP_MM_CLUS
**										TRIP_MM_ROT
**										TRIP_TV
**										TRIP_TV_ROT
**					descr			-	description of the trip (if any)
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetTripInfo(int *flag, TCHAR descr[TRIP_DESCR_LEN]){
	RETCOND		retCnd;
	TAGIDX		tiTrip;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	retCnd = GetTagIdx(TWN_TRIP_ALL, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_ALL;
		_stprintf_s(descr,sizeof(descr), _T("TRIP ALL"));
		return(RT_NORMAL);
	}

	//Bridge//	
	retCnd = GetTagIdx(TWN_TRIP_BRIDGE, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_BRIDGE;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TECH_STOP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Technological stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_MISAL, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Misalignment"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_SW_LIM, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("X/Y software limits"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_OC, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overcurrent"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_OS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overspeed"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_BRIDGE_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_LDT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Main mast loss during transport"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_LDT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Main mast cluster loss during transport"));
			return(RT_NORMAL);
		}
	}

	//Trolley//	
	retCnd = GetTagIdx(TWN_TRIP_TROLLEY, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_TROLLEY;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TECH_STOP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Technological stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_SW_LIM, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("X/Y software limits"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_OC, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overcurrent"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_OS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overspeed"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TROLLEY_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_LDT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Main mast loss during transport"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_LDT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Main mast cluster loss during transport"));
			return(RT_NORMAL);
		}
	}

	//MM//	
	retCnd = GetTagIdx(TWN_TRIP_FAGR, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_MM;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TECH_STOP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Technological stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_OC, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overcurrent"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_OL, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overload"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_UW, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Underweight"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_LW, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Loose of weight"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DC, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Difference with cluster"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_OS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overspeed"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}
	}
	
	//MM CL//	
	retCnd = GetTagIdx(TWN_TRIP_CLGR, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_MM_CLUS;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TECH_STOP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Technological stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_OC, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overcurrent"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_OL, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overload"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_UW, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Underweight"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_OS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overspeed"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_CL_NOT_EN, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Cluster not engaged"));
			return(RT_NORMAL);
		}
	}

	//MM ROT//	
	retCnd = GetTagIdx(TWN_TRIP_MM_ROT, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_MM_ROT;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TECH_STOP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Technological stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_ROT_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_ROT_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_ROT_45, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("45 degree control"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_ROT_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_ROT_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_ROT_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}
	}

	//TV//	
	retCnd = GetTagIdx(TWN_TRIP_TV, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_TV;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_OC, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overcurrent"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_OS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Overspeed"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_MAST_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}
	}

	//TV ROT//	
	retCnd = GetTagIdx(TWN_TRIP_TV_ROT, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_TV_ROT;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_ROT_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_ROT_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_ROT_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_ROT_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_TV_ROT_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}
	}

	//MM DISPL//	
	retCnd = GetTagIdx(TWN_TRIP_MM_DISP, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_MM_DISPL;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_MAX, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Max Force reached"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_MM_DISP_LOSS, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("MM loosening"));
			return(RT_NORMAL);
		}
	}

	//FALV//	
	retCnd = GetTagIdx(TWN_TRIP_FALV, &tiTrip);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tiTrip, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
		*flag = TRIP_FALV;

		retCnd = GetTagIdx(TWN_TRIP_FIRE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fire Protection"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_EMER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Emergency stop"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_WATER, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Water level low"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_RAD, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Excess radiation level"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_FALV_NP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("No permissive"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_FALV_TO, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Time out"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_FALV_TEMP, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Temperature"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_FALV_BRAKE, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Brake"));
			return(RT_NORMAL);
		}

		retCnd = GetTagIdx(TWN_TRIP_FALV_FAULT, &tagIdx);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		retCnd = TagRead(&tagIdx, &tagVal);
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
		if(GtBit((short int)(tagVal.value.val_di), 15) == 1){
			_stprintf_s(descr,sizeof(descr), _T("Fault"));
			return(RT_NORMAL);
		}
	}

	*flag = TRIP_OFF;
	_stprintf_s(descr,sizeof(descr), _T(""));

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		MastIsEmpty
**
** Description:		Check if any object is present on main mast
**
** Input:			---				- ---
**
** Output:			emptyFlag		- 1 - Mast is empty
**									  0 - Otherwise
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT MastIsEmpty(int *emptyFlag){
	RETSTAT		retSt;
	OBJTMM		mastSit;
	int			i;
	
	*emptyFlag = 0;

	retSt = GetMastSituation(&mastSit);
	if(retSt != RT_NORMAL){
		return(RT_FAILED);
	}

	for(i = 0; i < N_MAX_NONAM_OBJ; i++){
		if(mastSit.obj[i] != 0)
			return(RT_NORMAL);
	}

	*emptyFlag = 1;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		CellIsEmpty
**
** Description:		Check if any object is present in a cell
**
** Input:			mastType		- Mast to check
**
** Output:			emptyFlag		- 1 - Mast is empty
**									  0 - Otherwise
**
** Return:			RETSTAT			- RT_NORMAL	If flag has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT CellIsEmpty(short int cellVx, short int cellVy, int *emptyFlag){
	RETSTAT		retSt;
	OBJTCELL	cellSit;
	int			i;
	
	*emptyFlag = 0;

	retSt = GetCellSituation(cellVx, cellVy, &cellSit);
	if(retSt != RT_NORMAL){
		return(RT_FAILED);
	}

	for(i = 0; i < N_MAX_NONAM_OBJ; i++){
		if(cellSit.obj[i] != 0)
			return(RT_NORMAL);
	}

	*emptyFlag = 1;

	return(RT_NORMAL);
}

///////////////////////////////////////////////////////////////////////////////////////
//
//Routine che carica in database i nuovi set point per il Bridge e Trolley
//
RETCOND  Set_sp(float low_x,float high_x,float low_y,float high_y,TAGIDX TagIdx_Br_sp, TAGIDX TagIdx_Tr_sp)
{
 TAGINFO taginfo;
 RETCOND result= R_NORMAL;
 RETCOND eRet = R_NORMAL;

//carica in db i limiti low e high per il set point del bridge

 result = GetTagInfo( &TagIdx_Br_sp,DB_VAL0,&taginfo );
 if(result == R_NORMAL){
	taginfo.rValue = low_x;
 }
 else{
	eRet = R_FAILED;
 }
 result = SetTagInfo (&TagIdx_Br_sp, DB_VAL0, &taginfo, 0);
 if(result != R_NORMAL)	eRet = R_FAILED;

 result = GetTagInfo( &TagIdx_Br_sp,DB_VAL100,&taginfo );
 if(result == R_NORMAL){	taginfo.rValue = high_x;
 }
 else{ 
	eRet = R_FAILED;
 }
 result = SetTagInfo (&TagIdx_Br_sp, DB_VAL100, &taginfo, 0);
 if(result != R_NORMAL) eRet = R_FAILED;

//carica in db i limiti low e high per il set point del Trolley

 result = GetTagInfo( &TagIdx_Tr_sp,DB_VAL0,&taginfo );
 if(result == R_NORMAL){
	 taginfo.rValue = low_y;
 }
 else{
	eRet = R_FAILED;
 }
 result = SetTagInfo (&TagIdx_Tr_sp, DB_VAL0, &taginfo, 0);
 if(result != R_NORMAL) eRet = R_FAILED;

 result = GetTagInfo( &TagIdx_Tr_sp,DB_VAL100,&taginfo );
 if(result == R_NORMAL){
	taginfo.rValue = high_y;
 }
 else{
	eRet = R_FAILED;
 }
 result = SetTagInfo (&TagIdx_Tr_sp, DB_VAL100, &taginfo, 0);
 if(result != R_NORMAL) eRet = R_FAILED;

 return eRet;

}

//
//Routine che, dato il tagidx di un rcm restituisce un flag che segnala se c'e' il flag di permissivo
//

BOOL IsPerm(TAGIDX TagIdx_rcm)
{
	TAGVALEX TagVal = {0};
	RETCOND rs;
//Legge in rtdb il valore dell'rcm richiesto
	rs = TagRead (&TagIdx_rcm,&TagVal);
	if (rs != R_NORMAL )  return FALSE;

	if(GtBit((short int)(TagVal.value.val_di), 15) == 1)
		return TRUE;

	LPRCM_STATE pRcm = (LPRCM_STATE) &TagVal.value.val_di;
	if (pRcm->sp) return TRUE;
	return FALSE;
}

BOOL IsPermEx(TAGNAME TagName)
{
	TAGIDX	tagIdx;
	TAGVALEX TagVal = {0};
	RETCOND rs;
//Legge in rtdb il valore dell'rcm richiesto
	rs = GetTagIdx(TagName, &tagIdx);
	if (rs != R_NORMAL )  return FALSE;

	rs = TagRead (&tagIdx,&TagVal);
	if (rs != R_NORMAL )  return FALSE;

	if(GtBit((short int)(TagVal.value.val_di), 15) == 1)
		return TRUE;

	LPRCM_STATE pRcm = (LPRCM_STATE) &TagVal.value.val_di;
	if (pRcm->sp) return TRUE;
	return FALSE;
}

RETCOND SetTagSp(float low, float high, TAGIDX tagIdx){
	TAGINFO			taginfo;
	TAGVALEX		tagVal;
	RETCOND			result= R_NORMAL;
	RETCOND			eRet = R_NORMAL;

	//carica in db i limiti low e high per il set point del bridge

	result = GetTagInfo( &tagIdx,DB_VAL0,&taginfo );
	if(result == R_NORMAL){
		taginfo.rValue = low;
	}
	else{
		eRet = R_FAILED;
	}
	result = SetTagInfo (&tagIdx, DB_VAL0, &taginfo, 0);
	if(result != R_NORMAL)	eRet = R_FAILED;

	result = GetTagInfo( &tagIdx,DB_VAL100,&taginfo );
	if(result == R_NORMAL){
		taginfo.rValue = high;
	}
	else{ 
		eRet = R_FAILED;
	}
	result = SetTagInfo (&tagIdx, DB_VAL100, &taginfo, 0);
	if(result != R_NORMAL) 
		eRet = R_FAILED;

	result = TagRead(&tagIdx, &tagVal);
	if(result != R_NORMAL) 
		eRet = R_FAILED;

	result = TagWrite(&tagIdx, &tagVal, TAGWRITE_ACKNOWLEDGE);
	if(result != R_NORMAL) 
		eRet = R_FAILED;

	return eRet;
}

/*------------------------------------------------------------------------------
** Function:		ChangeZ1Page
**
** Description:		Change the Z1 mimic on TNT Explorer
**
** Input:			---				- ---
**
** Output:			---				- ---
**
** Return:			RETSTAT			- RT_NORMAL	If page has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT ChangeZ1Page(){
	RETSTAT		retSt;
	RETCOND		retCnd;
	GENIDX		contIdx;
	PAGNAM		pageName;

	retSt = GetDynCurrentCont(&contIdx);
	if(retSt != RT_NORMAL)
		return(RT_FAILED);

	if(contIdx == Z1_NO_CONT)
		_stprintf_s(pageName, _T("P_Z1_0"));
	else if(contIdx == Z1_CONT_TK13)
		_stprintf_s(pageName, _T("P_Z1_1"));
	else if(contIdx == Z1_CONT_LOAD)
		_stprintf_s(pageName, _T("P_Z1_2"));
	else if(contIdx == Z1_CONT_HECA)
		_stprintf_s(pageName,sizeof(pageName), _T("P_Z1_3"));
	else
		_stprintf_s(pageName, _T("P_Z1_0"));
		
	retCnd = CpSetPage(1, pageName);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		GetChannelInfo
**
** Description:		Return the two channels bypass status
**
** Output:			chan_A_ok		- Channel A is used
**					chan_B_ok		- Channel B is used
**
** Return:			RETSTAT			- RT_NORMAL	If info has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetChannelInfo(int *chan_A_ok, int *chan_B_ok){
	RETCOND		retCnd;
	TAGIDX		tagIdx;
	TAGVALEX	tagVal;

	*chan_A_ok = 0;
	*chan_B_ok = 0;

	retCnd = GetTagIdx(TWN_BYPASS_B, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
		*chan_A_ok = 0;
	else
		*chan_A_ok = 1;

	retCnd = GetTagIdx(TWN_BYPASS_A, &tagIdx);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(RT_FAILED);

	if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
		*chan_B_ok = 0;
	else
		*chan_B_ok = 1;

	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		GetPcuNum
**
** Description:		Return the PCU nimber to be used in read block functions
**
** Output:			---				- ---
**
** Return:			RETSTAT			- RT_NORMAL	If page has been set
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetPcuNum(int *pcu){
	RETSTAT		retSt;
	int			chan_A_ok;
	int			chan_B_ok;
	
	*pcu = 3;

	retSt = GetChannelInfo(&chan_A_ok, &chan_B_ok);
	if(retSt != RT_NORMAL)
		*pcu = 3;
	else if((chan_A_ok == 0) && (chan_B_ok == 1))
		*pcu = 4;
	else if((chan_A_ok == 1) && (chan_B_ok == 0))
		*pcu = 3;
	else if((chan_A_ok == 1) && (chan_B_ok == 1))
		*pcu = 3;
	else if((chan_A_ok == 0) && (chan_B_ok == 0))
		return(RT_FAILED);

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetCotainIdxFromCell
**
** Description:		Return the container IDX of a specified Z1 cell
**
** Input			vx				- Cell virtual X coordinate
**					vy				- Cell virtual Y coordinate
**
** Output:			contIdx			- Container identifier
**
** Return:			RETSTAT			- RT_NORMAL	If contIdx has been retrieved
**									- RT_FAILED	If errors occurred
*/
RETSTAT GetCotainIdxFromCell(int vx, int vy, int *contIdx){
	RETSTAT			retSt;
	RETCOND			retCnd;
	GENIDX			zoneIdx;
	FILEIDX			fileIdx;
	int				rec;
	int				i;
	t_cell			cell;

	*contIdx = -1;

	retSt = GetZoneIdxVirtCoo(vx, vy, &zoneIdx);
	if(retSt != RT_NORMAL)
		return(retSt);

	fileIdx.num = F_CE01;

	rec = 0;
	for(i = 1; i <= N_MAX_CELL; i++){
		retCnd = FileRead(&fileIdx, i, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			continue;

		if((cell.Virt_X == vx) && (cell.Virt_Y == vy))
			rec = i;
		else if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			break;
	}

	if(rec == 0)
		return(RT_FAILED);

	if((rec >= 1) && (rec <= CONT_TK13_CELLS))
		*contIdx = Z1_CONT_TK13;
	else if((rec > CONT_TK13_CELLS) && (rec <= (CONT_LOAD_CELLS + CONT_TK13_CELLS)))
		*contIdx = Z1_CONT_LOAD;
	else if((rec > (CONT_LOAD_CELLS + CONT_TK13_CELLS)))
		*contIdx = Z1_CONT_HECA;

	return(RT_NORMAL);
}

RETSTAT GetMMTVDistance(float *dist){
	RETSTAT		retSt;
	float		temp;

	temp = 0.0;
	*dist = 0.0;

	retSt = GetInfiBlockValEx(8005, 0, TUNE_FROM_DAFS, &temp);
	if(retSt == RT_NORMAL)
		*dist = temp;
	else
		return(RT_FAILED);

	return(RT_NORMAL);
}

RETSTAT GetPositToll(float *toll){
	RETSTAT		retSt;
	float		temp;

	temp = 0.0;
	*toll = 0.0;
	retSt = GetInfiBlockValEx(8006, 0, TUNE_FROM_DAFS, &temp);
	if(retSt == RT_NORMAL)
		*toll = temp;
	else
		return(RT_FAILED);

	return(RT_NORMAL);	
}

/*------------------------------------------------------------------------------
** Function:		GetDynSPRefresh
**
** Description:		Retrieve Set points limits refresh flag from F_DYNP
**
** Input			spReferesh	- SP limits refresh flag
**					
** Return:			RETSTAT		- RT_NORMAL	If spReferesh has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetDynSPRefresh(int *spReferesh){
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	*spReferesh = dyn.refreshSp;

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		SetDynSPRefresh
**
** Description:		Set Set points limits refresh flag from F_DYNP
**
** Input			spReferesh	- SP limits refresh flag
**					
** Return:			RETSTAT		- RT_NORMAL	If spReferesh has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetDynSPRefresh(int spReferesh){
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	dyn.refreshSp = spReferesh;

	retSt = SetDynStruc(dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		GetDynSPReloadPar
**
** Description:		Retrieve Set points limits parametrs reload flag from F_DYNP
**
** Input			spReferesh	- SP limits parameters reload flag
**					
** Return:			RETSTAT		- RT_NORMAL	If spReload has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT GetDynSPReloadPar(int *spReload){
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	*spReload = dyn.reloadSpPar;

	return(RT_NORMAL);

}

/*------------------------------------------------------------------------------
** Function:		SetDynSPReloadPar
**
** Description:		Set Set points limits refresh flag from F_DYNP
**
** Input			spReload	- SP limits parameers reload flag
**					
** Return:			RETSTAT		- RT_NORMAL	If spReload has been set
**								- RT_FAILED	If errors occurred
*/
RETSTAT SetDynSPReloadPar(int spReload){
	RETSTAT			retSt;
	dynamic_struc	dyn;

	retSt = GetDynStruc(&dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	dyn.reloadSpPar = spReload;

	retSt = SetDynStruc(dyn);
	if(retSt != RT_NORMAL)
		return(retSt);
	
	return(RT_NORMAL);

}

/********************************************************************************************/
/*																							*/
/*	Function:		SetWeightOnMast															*/
/*																							*/
/*	Description:	Set the expected weight tags for manual modes							*/
/*																							*/
/*	Input:			mastSituation		-	Mast situation									*/
/*																							*/
/*	Return:			retSt				-	RT_NORMAL	for success							*/
/*										-	RT_FAILED	otherwise							*/
/*																							*/
/********************************************************************************************/
RETSTAT SetWeightOnMast(OBJTMM mastSituation){
	RETSTAT			retstat;
	float			weight;
	float			objWeight;
	float			clgrWeight;
	int				j;

	//Controllo il peso sul mast.//
	clgrWeight = 0.0;
	if((mastSituation.obj[OBJT_N_CLUS] != 0) && (mastSituation.obj[OBJT_N_CLUS_CAS] != 0)){
		retstat = GetObjWeight(mastSituation.o_id[OBJT_N_CLUS], &objWeight);
		if(retstat != RT_NORMAL)
			return (RT_INVOBJ);
		clgrWeight = objWeight;
	}

	weight = 0.0;
	objWeight = 0.0;
	for(j = 0; j < N_MAX_NONAM_OBJ; j++){
		if(mastSituation.obj[j] != 0){
			if(j < N_MAX_NAMED_OBJ){
				if(((j == OBJT_N_CLUS) && (mastSituation.obj[OBJT_N_CLUS_CAS] == 0)) || (j != OBJT_N_CLUS)){
					retstat = GetObjWeight(mastSituation.o_id[j], &objWeight);
					if(retstat != RT_NORMAL)
						return (retstat);
				}
			}
			else{
				retstat = GetObjtWeight(mastSituation.obj[j], &objWeight);
				if(retstat != RT_NORMAL)
					return (RT_INVOBJT);
			}
			weight = weight + objWeight;
		}
	}
 
	retstat = VotedTagWrite(TWN_MM_EXP_WEIGHT, 0, weight, FLT_VALUE);
	if(retstat != RT_NORMAL)
		return(retstat);
		
	retstat = VotedTagWrite(TWN_MM_CL_EXP_WEIGHT, 0, clgrWeight, FLT_VALUE);
	if(retstat != RT_NORMAL)
		return(retstat);
	

	return(RT_NORMAL);
}

/********************************************************************************************/
/*																							*/
/*	Function:		GetFALVOffset															*/
/*																							*/
/*	Description:	Get the FALV offset from Infi90 blocks									*/
/*																							*/
/*	Output:			x_off				-	x offset										*/
/*					y_off				-	y offset										*/
/*																							*/
/*	Return:			retSt				-	RT_NORMAL	for success							*/
/*										-	RT_FAILED	otherwise							*/
/*																							*/
/********************************************************************************************/
RETSTAT GetFALVOffset(float *x_off, float *y_off){
	RETSTAT		retSt;
	float		val;

	*x_off = 0.0;
	*y_off = 0.0;


	retSt = GetInfiBlockValEx(8345, 0, TUNE_FROM_DAFS, &val);
	if(retSt != RT_NORMAL)
		*x_off = OFFSET_X_FC_MAST;
	else
		*x_off = val;

	retSt = GetInfiBlockValEx(8346, 0, TUNE_FROM_DAFS, &val);
	if(retSt != RT_NORMAL)
		*y_off = OFFSET_Y_FC_MAST;
	else
		*y_off = val;

	return(RT_NORMAL);
}

/********************************************************************************************/
/*																							*/
/*	Function:		GetMMRotToll															*/
/*																							*/
/*	Description:	Get Main Mast Rotation													*/
/*																							*/
/*	Output:			rotToll				-	Rtotation Tollerance							*/
/*																							*/
/*	Return:			retSt				-	RT_NORMAL	for success							*/
/*										-	RT_FAILED	otherwise							*/
/*																							*/
/********************************************************************************************/
RETSTAT GetMMRotToll(float *rotToll){
	RETSTAT		retSt;
	float		val;

	*rotToll = 0.0;

	retSt = GetInfiBlockValEx(8545, 0, TUNE_FROM_DAFS, &val);
	if(retSt != RT_NORMAL)
		*rotToll = TOLL_MM_GR;
	else
		*rotToll = val;

	return(RT_NORMAL);
}

/********************************************************************************************/
/*																							*/
/*	Function:		GetErrMsg																*/
/*																							*/
/*	Description:	Retrieve a TC error message from code									*/
/*																							*/
/*	Output:			code				-	Error code										*/
/*																							*/
/*	Return:			retSt				-	RT_NORMAL	for success							*/
/*										-	RT_FAILED	otherwise							*/
/*																							*/
/********************************************************************************************/
RETSTAT GetErrMsg(GENIDX code, TCHAR msg[TC_ERR_LEN + 1]){
	RETCOND			retCnd;
	FILEIDX			fileIdx;
	int				rec;
	t_tcErr			tcErr;

	fileIdx.num = F_TCER;

	for(rec = 1; rec <= TC_ERR_REC; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &tcErr, sizeof(t_tcErr));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(tcErr.errCode == code){
			_stprintf_s(msg,sizeof(msg), _T("%s"), tcErr.errDescr);
			return(RT_NORMAL);
		}
	
	}

	return(RT_FAILED);
}

/********************************************************************************************/
/*																							*/
/*	Function:		MakeZ3Spent																*/
/*																							*/
/*	Description:	Convert all object in Z3 to spent										*/
/*																							*/
/*	Output:			numFA				- Number of changed FAs								*/
/*					numCl				- Number of changed clusters						*/
/*																							*/
/*	Return:			retSt				-	RT_NORMAL	for success							*/
/*										-	RT_FAILED	otherwise							*/
/*																							*/
/********************************************************************************************/
RETSTAT MakeZ3Spent(int *numFA, int *numCl){
	RETSTAT			retSt;
	RETCOND			retCnd;
	GENIDX			zoneIdx;
	GENIDX			nfaIdx;
	GENIDX			nclIdx;
	GENIDX			sfaIdx;
	GENIDX			sclIdx;
	FILEIDX			fileIdx;
	t_cell			cell;
	int				rec;
	int				countFA;
	int				countCl;
	bool			change;

	retSt = GetZoneIdx(ZONE_REACTOR, &zoneIdx);
	if(retSt != RT_NORMAL)
		return retSt;

	fileIdx.num = F_CE01 + zoneIdx - 1;

	retSt = GetObjtIdx(_T("N_FA"), &nfaIdx);
	retSt = GetObjtIdx(_T("N_CL"), &nclIdx);
	retSt = GetObjtIdx(_T("S_FA"), &sfaIdx);
	retSt = GetObjtIdx(_T("S_CL"), &sclIdx);

	countFA = 0;
	countCl = 0;
	*numFA = 0;
	*numCl = 0;
	for(rec = 1; rec <= N_MAX_CELL; rec++){
		change = false;
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		if(cell.objt_cell.obj[OBJT_N_FA] == nfaIdx){
			retSt = PutObjObjtIdx(cell.objt_cell.o_id[OBJT_N_FA], sfaIdx);
			if(retSt != RT_NORMAL)
				return(RT_FAILED);
			
			cell.objt_cell.obj[OBJT_N_FA] = sfaIdx;

			change = true;
			countFA++;
		}

		if(cell.objt_cell.obj[OBJT_N_CLUS] == nclIdx){
			retSt = PutObjObjtIdx(cell.objt_cell.o_id[OBJT_N_CLUS], sclIdx);
			if(retSt != RT_NORMAL)
				return(RT_FAILED);
			
			cell.objt_cell.obj[OBJT_N_CLUS] = sclIdx;

			change = true;
			countCl++;
		}

		if(change){
			retCnd = FileWrite(&fileIdx, rec, 1, &cell, sizeof(t_cell));
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
		}
	}

	*numFA = countFA;
	*numCl = countCl;

	return(RT_NORMAL);
}

/********************************************************************************************/
/*																							*/
/*	Function:		EmptyZ1Cont																*/
/*																							*/
/*	Description:	Convert all object in Z3 to spent										*/
/*																							*/
/*	Input:			contIdx				- Z1 container to empty								*/
/*	Output:			---					- ---												*/
/*																							*/
/*	Return:			retSt				- RT_NORMAL	for success								*/
/*										- RT_FAILED	otherwise								*/
/*																							*/
/********************************************************************************************/
RETSTAT EmptyZ1Cont(GENIDX contIdx){
	RETSTAT		retSt;
	RETCOND		retCnd;
	GENIDX		zoneIdx;
	FILEIDX		fileIdx;
	FILEIDX		fileObje;
	t_cell		cell;
	t_obj		obj_e;
	int			rec;
	int			startRec;
	int			stopRec;
	int			i;
	int			irec;

	retSt = GetZoneIdx(ZONE_IO, &zoneIdx);
	if(retSt != RT_NORMAL)
		return retSt;

	fileIdx.num = F_CE01 + zoneIdx - 1;
	fileObje.num = F_OBJE;

	if(contIdx == Z1_CONT_TK13){
		startRec = 1;
		stopRec = CONT_TK13_CELLS;
	}else if(contIdx == Z1_CONT_LOAD){
		startRec = CONT_TK13_CELLS + 1;
		stopRec = CONT_TK13_CELLS + CONT_LOAD_CELLS;
	}else if(contIdx == Z1_CONT_HECA){
		startRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + 1;
		stopRec = CONT_TK13_CELLS + CONT_LOAD_CELLS + CONT_HECA_CELLS;
	}else
		return(RT_FAILED);

	for(rec = startRec; rec <= stopRec; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);

		for(i = 0; i < N_MAX_NONAM_OBJ; i++){
			if(i < N_MAX_NAMED_OBJ){
				if((cell.objt_cell.o_id[i] != 0) && (cell.objt_cell.obj[i] != 0)){
					for(irec = 1; irec <= N_MAX_OBJ; irec++){
						retCnd = FileRead(&fileObje, irec, 1, &obj_e, sizeof(obj_e));
						if(retCnd != R_NORMAL)
							continue;
						
						if(obj_e.idx == cell.objt_cell.o_id[i]){
							ZeroMemory(&obj_e, sizeof(t_obj));
							retCnd = FileWrite(&fileObje, irec, 1, &obj_e, sizeof(obj_e));
							break;
						}

					}

					cell.objt_cell.obj[i] = 0;
					cell.objt_cell.o_id[i] = 0;
				}else if((cell.objt_cell.o_id[i] != 0) && (cell.objt_cell.obj[i] == 0)){
					return(RT_FAILED);
				}else if((cell.objt_cell.o_id[i] == 0) && (cell.objt_cell.obj[i] != 0)){
					return(RT_FAILED);
				}
			}else
				cell.objt_cell.obj[i] = 0;
		}

		retCnd = FileWrite(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(RT_FAILED);
	}

	return(RT_NORMAL);
}

/*------------------------------------------------------------------------------
** Function:		isInRange
**
** Description:		
**
** Input:			f1			- float number
** Input:			f2			- float number
** Input:			f3			- float number
**
** Return:			BOOL		- TRUE f2 <= f1 <= f3
**								- FALSE f1 < f2
*/

BOOL isInRange	( float f1, float f2, float f3 )
{
	
	float epsilon;
	epsilon = (float)0.00001;

  if ( (f1-f2 > - epsilon) &&  (f3-f1 > - epsilon) )
	  return TRUE;
  else
	  return FALSE;
}